Mouse Double Click - MOUSE MULTI CLICK !

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

Mouse Double Click - MOUSE MULTI CLICK !

Post by Ulf »

NOTE:
This thread has been moved from the thread RECT (rectangle) class additions. Are they are useful?
I made the mistake of mixing 2 threads.
So I'm splitting them and moving both. In this post, I am replying to comments made by CuteAlien in reference to my double click event.

MOUSE DOUBLE CLICK
I'm working on adding a double click event.
I built the double click straight into the engine rather than changing the IGUIEnvironment and CGUIEnvironment as jox did for some unknown obscure reason??
http://irrlicht.sourceforge.net/phpBB2/ ... uble+click

I don't think jox's code works :shock:, certainly doesn't look like it.
For double-clicks - certainly useful, but should preferably be platform independent. And that might even be the reason why they are not in yet (at least the reason why I have not added my patch for that so far), because doing that is a little more work than just passing on the corresponding events.
Where is the extra work?
This is how I did the double click. It's simple. It's platform independent. I based it on jox's idea, but it works perfectly and makes sense.

Add the following in "CIrrDeviceStub.h"

Code: Select all

//! Added by Ulf
//! Used internaly by the IrrDevices to check if a double-click has occured.
virtual bool isDoubleClick(const SEvent& event, u32 time);

//! Added by Ulf
//! Sets the double-click speed in milliseconds.
virtual void setDoubleClickSpeed(u32 speed);

//! Added by Ulf
//! Used internaly by the IrrDevices to check if a double-click has occured.
struct SDoubleClick
{
   SDoubleClick() : Speed(300),Time(0), X(0), Y(0), Type(EMIE_COUNT) {}
   u32 Speed; // speed in milliseconds
   u32 Time;  // time of last click
   s32 X, Y;  // mouse coordinates of last click
   EMOUSE_INPUT_EVENT Type;   // type of event e.g. EMIE_LMOUSE_DOUBLE_CLICKED
};
SDoubleClick DoubleClick;
And Add the following in "CIrrDeviceStub.cpp"

Code: Select all

//! Added by Ulf
//! Used internaly by the IrrDevices to check if a double-click has occured.
bool CIrrDeviceStub::isDoubleClick(const SEvent& event, u32 time)
{
   bool isDoubleClick = false;

   if (time - DoubleClick.Time < DoubleClick.Speed // make sure the 2nd click has happened within the double click speed
      && DoubleClick.Type == event.MouseInput.Event // make sure it's the same mouse button
      && event.MouseInput.X == DoubleClick.X // make sure the mouse hasn't moved
      && event.MouseInput.Y == DoubleClick.Y)
   {
      /** Note: This is a double click, so set the double click time to 0
      so the next click can't be a double click. */
      DoubleClick.Time = 0;
      isDoubleClick = true;
   }
   else
   {
      /** Note: This is the first click, so set the double click time to the
      click time so we can check for double click later. */
      DoubleClick.Time = time;
   }
   //! Set location of mouse click so we can check if the mouse moved since last click.
   DoubleClick.X = event.MouseInput.X;
   DoubleClick.Y = event.MouseInput.Y;

   //! Set the event type so we can check if it's the same mouse button as the previous click.
   DoubleClick.Type = event.MouseInput.Event;

   return isDoubleClick;
}

//! Added by Ulf
//! Sets the double-click speed in milliseconds.
void CIrrDeviceStub::setDoubleClickSpeed(u32 speed)
{
   DoubleClick.Speed = speed;
}
Then in each implementation of the device such as in "CIrrDeviceWin32.cpp" put the following:

Code: Select all

//! Modified by Ulf
/** Note: Now takes care of double clicks. */
case WM_LBUTTONDOWN:
   ++ClickCount; //! Modified by Ulf
   SetCapture(hWnd);
   event.EventType = irr::EET_MOUSE_INPUT_EVENT;
   event.MouseInput.Event = irr::EMIE_LMOUSE_PRESSED_DOWN;
   event.MouseInput.X = (short)LOWORD(lParam);
   event.MouseInput.Y = (short)HIWORD(lParam);
   dev = getDeviceFromHWnd(hWnd);
   if (dev)
   {
      //! Get click time as soon as we can.
      irr::u32 clickTime = dev->getTimer()->getTime();

      //! Post the left button press event
      dev->postEventFromUser(event);

      //! Post a double click event if it was a double click.
      if (dev->isDoubleClick(event, clickTime))
      {
         event.MouseInput.Event = irr::EMIE_LMOUSE_DOUBLE_CLICKED;
         dev->postEventFromUser(event);
      }
   }
   return 0;
Note: Obviously, it needs to be done for each button.

Or for Linux "CirrDeciceLinux.cpp" put:

Code: Select all

case ButtonPress:
   //! Added by Ulf
   //! Get click time as soon as we can. For double click checking.
   irr::u32 clickTime = this->getTimer()->getTime();

case ButtonRelease:
   irrevent.EventType = irr::EET_MOUSE_INPUT_EVENT;
   irrevent.MouseInput.X = event.xbutton.x;
   irrevent.MouseInput.Y = event.xbutton.y;

   irrevent.MouseInput.Event = irr::EMIE_COUNT;

        switch(event.xbutton.button)
   {
   case  Button1:
      irrevent.MouseInput.Event =
         (event.type == ButtonPress) ? irr::EMIE_LMOUSE_PRESSED_DOWN : irr::EMIE_LMOUSE_LEFT_UP;
      break;

   case  Button3:
      irrevent.MouseInput.Event =
         (event.type == ButtonPress) ? irr::EMIE_RMOUSE_PRESSED_DOWN : irr::EMIE_RMOUSE_LEFT_UP;
      break;

   case  Button2:
      irrevent.MouseInput.Event =
         (event.type == ButtonPress) ? irr::EMIE_MMOUSE_PRESSED_DOWN : irr::EMIE_MMOUSE_LEFT_UP;
      break;

   case  Button4:
      irrevent.MouseInput.Event = EMIE_MOUSE_WHEEL;
      irrevent.MouseInput.Wheel = 1.0f;
      break;

   case  Button5:
      irrevent.MouseInput.Event = EMIE_MOUSE_WHEEL;
      irrevent.MouseInput.Wheel = -1.0f;
      break;
   }

        if (irrevent.MouseInput.Event != irr::EMIE_COUNT)
   {
                //! Post the button press event
      postEventFromUser(irrevent);
   
      //! Added by Ulf
      //! Post a double click event, if it was a double click.
      if (this->isDoubleClick(event, clickTime))
      {
         switch (event.MouseInput.Event)
         {
         case EMIE_LMOUSE_PRESSED_DOWN:
            event.MouseInput.Event = irr::EMIE_LMOUSE_DOUBLE_CLICKED;
            break;
         case EMIE_RMOUSE_PRESSED_DOWN:
            event.MouseInput.Event = irr::EMIE_RMOUSE_DOUBLE_CLICKED;
            break;
         case EMIE_MMOUSE_PRESSED_DOWN:
            event.MouseInput.Event = irr::EMIE_MMOUSE_DOUBLE_CLICKED;
            break;
         }
         dev->postEventFromUser(event);
      }
   }
   break;
That's all 3 buttons in Linux.

And.. That's it! for Windows and Linux.

By the way, which is the MAC implementation? What is the SDL implementation? Is that for Windows? I haven't looked at it yet.
X11 does not have an event for this, so we need to care about double-click time ourselves. Which now leaves the question - what to use on Windows if we already have to care about time in the engine: The own double-click, just the system-double-click or an own double-click initialized with system-time for double-clicks?
Maybe for it to be consistent between platforms it should NOT use the Windows built in double click events e.g. WM_LBUTTONDBLCLK. But I don't think it really matters too much. It's just timing.
Or maybe it should use WM_LBUTTONDBLCLK because windows is already handling the event so it would be more efficient, matching the efficiency of the Linux implementation that I provided..?
Not sure what others would prefer here. Also there's the question if a doubleclick-event is additionally a click-event.
I believe that in Windows a double click posts a click event, then a double click event. Can anyone confirm?
Also that seems to be the general consensus as far as what is wanted or needed. It is still a click after all! Yes?
Feedback on that always welcome - I haven't found time yet to dig deeper into that. But it's something I've already missed myself a few times.
Great, cause I want to improve it... and I have! :twisted:
I think so.

Note: All this code works. I am implementing extra buttons into my irrlicht too!
So any help and knowledge from anyone about extra mouse buttons would be great.

For example, can more than 3 buttons be accessed in Linux?
It only seems to have 5 buttons defined, and 4 and 5 are the mouse wheel.
I know that doesn't mean more buttons can't be accessed.
So, what I wanted to know is, do extra mouse buttons in Linux work same as in Windows, as follows:

Code: Select all

/* XButton values are WORD flags */
#define XBUTTON1 0x0001
#define XBUTTON2 0x0002
/* Were there to be an XBUTTON3, its value would be 0x0004 */
More precisely, I mean, in Linux are Button1 to Button5 defined as values 1, 2, 4, 8, 16.
And are the extra buttons accessed as values 32, 64, 128 and so on?
Or are there only 3 actual mouse buttons in Linux event system?

My quote: (from this post)
I believe that in Windows a double click posts a click event, then a double click event. Can anyone confirm?
Also that seems to be the general consensus as far as what is wanted or needed. It is still a click after all! Yes?
One point.
It MUST post a click event, and then a double click.
Or else when you don't do anything for double clicks, you won't receive the 2nd click event! Yes? Yes. :D
Last edited by Ulf on Thu Jul 02, 2009 5:33 pm, edited 2 times in total.
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

Post by Ulf »

hybrid replied to me with the following:
Ulf wrote:
Yes inflate compiles and works. Why wouldn't it?
Because you have used a wrong parameter name.

A general question: Where's set to be favored over assignment of a newly generated object? so writing r.set(x,y,z,a) should be largely equivalent in run-time to r=recti(x,y,z,a). So maybe we should instead deprecate the set methods instead?

I can confirm that X does not have a double-click event, only button_press and button_release messages are sent. This means that we need to send a button_press and button_release for every event, but also send a double click (and triple click?) for thos events that are fast enough. This must not rely on system dependent values, and the double click latency should use an Irrlicht default value, not a system dependent.
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

Post by Ulf »

CuteAlien replied next with this:

Thanks for the work. I can't promise I find time this weekend already (some other patches on my todo), but I'll try to care at least about the double-click asap.
Ulf wrote:
This is how I did the double click. It's simple. It's platform independent. I based it on jox's idea, but it works perfectly and makes sense.
I see - so you completely avoid using the Windows doubleclick. I still would like to find out the current speed-value which the system has for double-clicks if that is possible. So that value could be used for original initialization (which is btw. right now missing in the patch - speed is not initialized and therefore random). Also not sure if mouse-movement should be cared about in doubleclicks. I just checked on Linux in Firefox and movement is ignored there (but that could also be specific to the graphic-lib used by firefox). Can you check on Windows?

My question about sending doubleclick additional to click was pointless as I just noticed that Irrlicht has no click-event anyway ;-) So yeah, pressed-down and then double-click is the correct order.

The part with "case WM_LBUTTONDOWN" does no longer exist in the engine, that stuff was rewritten in current trunk. So have to see how that must be added in current Irrlicht.
Ulf wrote:
By the way, which is the MAC implementation? What is the SDL implementation? Is that for Windows? I haven't looked at it yet.
Don't know - I also haven't looked yet. I can probably check for SDL, but I can't compile Mac.
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

Post by Ulf »

CuteAlien then said:
hybrid wrote:
This must not rely on system dependent values, and the double click latency should use an Irrlicht default value, not a system dependent.
OK, I guess if someone wants to use system settings for that he can still do so. I'm always a little reluctant coding stuff which is already coded by the OS, but I guess not much of a choice when you want to be platform independent :-(
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

My Post

Post by Ulf »

I can confirm that X does not have a double-click event, only button_press and button_release messages are sent.
Yes I saw that Linux didn't have a double click. That's why I didn't use WM_LBUTTONDBLCLK etc. for the Windows double click. I did it the same as the Linux. But it's even easier to use the windows double click events.
This means that we need to send a button_press and button_release for every event, but also send a double click (and triple click?) for thos events that are fast enough. This must not rely on system dependent values, and the double click latency should use an Irrlicht default value, not a system dependent.
If so, then the Windows implementation should be as I did it.
The same as the Linux, using the DoubleClick struct, and testing for double click in the single click event section, then posting the click and the double click if it's within the time limit.

I don't think triple clicks are useful, or practical actually. Anyone else?

Hybrid, you seem to know something about Linux.
Can Linux access more than 3 mouse buttons? (not including 4 & 5 which are the mouse wheel)

Because I have implemented the extra buttons into the windows version. It's untested as I need to get a mouse with more than 3 buttons! :?
By the way, I had to include several extra defines in the function

Code: Select all

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
Irrlicht already defines the mouse wheel there..

Code: Select all

#ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020A
#endif
#ifndef WHEEL_DELTA
#define WHEEL_DELTA 120
#endif
I'll get back with that in a week or so.
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

Post by Ulf »

I still would like to find out the current speed-value which the system has for double-clicks if that is possible. So that value could be used for original initialization (which is btw. right now missing in the patch - speed is not initialized and therefore random)
Cutie Alien,
I'm not sure what you mean. Missing from my patch? I set the speed to 300ms in the DoubleClick struct. It can be modified at run-time.
Windows double click speed can be set in the GUI as well. Open Mouse settings in Control Panel. It doesn't show a value, but can be changed.

By default, Windows double click speed is 500ms, apparently.

http://www.downloadsquad.com/2008/04/28 ... d-setting/

The website recommends setting it at more like 250ms. 300 seems fine.
Also not sure if mouse-movement should be cared about in doubleclicks. I just checked on Linux in Firefox and movement is ignored there (but that could also be specific to the graphic-lib used by firefox). Can you check on Windows?
Yes in Windows, it matters. It should matter.
You don't want to double click on something that you are moving across.
If you want to double click something then you want to point at it.
Otherwise it's not a double click, it's random fast clicking :lol: hahaha.

There is one thing I noticed. I been testing, and it appears that a mouse move event is triggered after a mouse button Release. Not after a mouse press, just release. Does that seem normal or correct? I don't figure that as any kind of problem.
The part with "case WM_LBUTTONDOWN" does no longer exist in the engine, that stuff was rewritten in current trunk. So have to see how that must be added in current Irrlicht.
Huh? How can it not be? It's a Windows event handler and so must use the Windows parameters! Not sure what you mean. I have to look and see.
What, have they made their own definitions? What for? Anyway...
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

CuteAlien wrote:Also not sure if mouse-movement should be cared about in doubleclicks. I just checked on Linux in Firefox and movement is ignored there (but that could also be specific to the graphic-lib used by firefox). Can you check on Windows?
As the great Joel Spolsky says all n's are equally likely is bad, Microsoft actually allow for a slight movement of about 3x3 pixels before cancelling a double-click (at least in explorer).

The big question is whether this is a GUI or OS problem. If an OS problem then we should let the devices deal with it, if it's a GUI problem then we should probably add parameters to the GUI and maybe retrieve defaults from os.h or something.
Ulf wrote:By the way, which is the MAC implementation? What is the SDL implementation? Is that for Windows? I haven't looked at it yet.
SDL only has SDL_MOUSEBUTTONDOWN and SDL_MOUSEBUTTONUP, so it would be a pain. Cocoa (OSX) has a clickCount for double/triple clicks, so it should be really easy.
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

Post by Ulf »

As the great Joel Spolsky says all n's are equally likely is bad
So, you think it should allow for no movement at all?
Microsoft actually allow for a slight movement of about 3x3 pixels before cancelling a double-click (at least in explorer)
What, for people with Parkinsons?
Ok. Either way, that's not hard to do.
The big question is whether this is a GUI or OS problem.
I suppose we need to discover if it's op system or gui.
I'd "guess" it's gui. I like guessing.. hehe, as it's not important to me.
I don't believe it matters! Are we trying to emulate Win32? or Linux? No we need our implementation, so long it works the same on all platforms.
If an OS problem then we should let the devices deal with it, if it's a GUI problem then we should probably add parameters to the GUI and maybe retrieve defaults from os.h or something.
But then it will be platform dependent. Can't we establish our own idea. Why does it have to be like Windows or Linux. Especially if they are different to each other.

Why get the operating system default. Let's make our own!
Someone, take charge! hehe. :shock:

It's just cosmetic. How do we want it to work?
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
CuteAlien
Admin
Posts: 9988
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Ulf wrote:I set the speed to 300ms in the DoubleClick struct.
Sorry, missed that.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

Post by Ulf »

I forgot to say, we need to add the extra mouse input events to EMOUSE_INPUT_EVENT in "IEventReceiver.h".

Code: Select all

EMIE_LMOUSE_DOUBLE_CLICKED
EMIE_RMOUSE_DOUBLE_CLICKED
EMIE_MMOUSE_DOUBLE_CLICKED
Also, the SDL version is the same as Linux.

Ummm... I still don't get it. Which is the MAC version of the Irrlicht driver class?
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
CuteAlien
Admin
Posts: 9988
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

bitplane wrote:
CuteAlien wrote:Also not sure if mouse-movement should be cared about in doubleclicks. I just checked on Linux in Firefox and movement is ignored there (but that could also be specific to the graphic-lib used by firefox). Can you check on Windows?
As the great Joel Spolsky says all n's are equally likely is bad, Microsoft actually allow for a slight movement of about 3x3 pixels before cancelling a double-click (at least in explorer).
Always difficult to wrap my mind around such strange concepts ;-) But it actually explains the behaviour I seem to have on Linux also better than a strict movement/no movement distinction.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

MOUSE MULTI CLICK

Post by Ulf »

I thought about my comment:
I don't think triple clicks are useful, or practical actually. Anyone else?
However after watching a lecture about designing api's I thought, how about unlimited multiclick event handling?

No it doesn't make sense, after thinking about it.

Damn.. I'm going crazy..
I should start going to sleep before 7 am.
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

Post by Ulf »

I was over confident and then under confident.

I've thought about it for 10 minutes and I think I can do the MULTI click event handler, and quite simply.

But the easiest way to do it requires a modification to SMouseInput.

Code: Select all

//! Any kind of mouse event.
struct SMouseInput
{
	//! X position of mouse cursor
	s32 X;

	//! Y position of mouse cursor
	s32 Y;

	//! mouse wheel delta, usually 1.0 or -1.0.
	/** Only valid if event was EMIE_MOUSE_WHEEL */
	f32 Wheel;

	//! Type of mouse event
	EMOUSE_INPUT_EVENT Event;

        //! Stores the number of consecutive multi-clicks
	u32 MultiClick;
};
NOTE: I am copying the code from my other posts and modifying on the fly! I'll try to compile it in my head :lol:

Here it is:
Firstly, we now must remove what I said to put into EMOUSE_INPUT_EVENT in "IEventReceiver.h".

Code: Select all

EMIE_LMOUSE_DOUBLE_CLICKED
EMIE_RMOUSE_DOUBLE_CLICKED
EMIE_MMOUSE_DOUBLE_CLICKED 
So make sure that's back to the original irrlicht version.
The beauty of it is, we don't need those defines anymore. :D
But then we need to create

In "CIrrDeviceStub.h" replace the functions and DoubleClick struct with

Code: Select all

//! return: Returns the number of multi-clicks that have accumulated
virtual u32 getMultiClick(const SEvent& event, u32 time);

virtual void setMultiClickSpeed(u32 speed);

struct SMultiClick
{
   SMultiClick() : Speed(300),Time(0), X(0), Y(0), Type(EMIE_COUNT), AccumulatedClicks(0) {}
   u32 Speed; // speed in milliseconds
   u32 Time;  // time of last click
   s32 X, Y;  // mouse coordinates of last click
   EMOUSE_INPUT_EVENT Type;   // type of event e.g. EMIE_LMOUSE_CLICKED
   u32 AccumulatedClicks; // track how many multi-clicks have accumulated
};
SMultiClick MultiClick; 
In "CIrrDeviceStub.cpp"

Code: Select all

u32 CIrrDeviceStub::getMultiClick(const SEvent& event, u32 time)
{
   if (time - MultiClick.Time < MultiClick.Speed // make sure the next click has happened within the multi click speed
      && MultiClick.Type == event.MouseInput.Event // make sure it's the same mouse button
      && event.MouseInput.X == MultiClick.X // make sure the mouse hasn't moved
      && event.MouseInput.Y == MultiClick.Y)
   {//! This is a multi-click
        MultiClick.AccumulatedClicks++; // increment the multi-click counter;
   }
   else
   {//! This is NOT a multi-click
     	MultiClick.AccumulatedClicks = 0; // reset multi-click counter
   }

   //! set the click time, so we can test next click for click speed and decide if it's a multi-click
   MultiClick.Time = time;

   //! Set location of mouse click so we can check next click and if the mouse moved.
   MultiClick.X = event.MouseInput.X;
   MultiClick.Y = event.MouseInput.Y;

   //! Set the event type so we can check next click if it's the same mouse button as the previous click.
   MultiClick.Type = event.MouseInput.Event;

   return MultiClick.AccumulatedClicks;
}

//! Sets the multi-click speed in milliseconds.
void CIrrDeviceStub::setMultiClickSpeed(u32 speed)
{
   MultiClick.Speed = speed;
} 
And then, just showing how the Windows version would be implemented (since it's taken me more than 1 hour to do this right now on the fly :? )
Modify "CIrrDeviceWin32.cpp"

Code: Select all

case WM_LBUTTONDOWN:
	++ClickCount; //! Modified by Patrick Bucher
	SetCapture(hWnd);
	event.EventType = irr::EET_MOUSE_INPUT_EVENT;

	event.MouseInput.Event = irr::EMIE_LMOUSE_PRESSED_DOWN;
	event.MouseInput.X = (short)LOWORD(lParam);
	event.MouseInput.Y = (short)HIWORD(lParam);

	dev = getDeviceFromHWnd(hWnd);
	if (dev)
	{
		//! Get click time as soon as we can.
		clickTime = dev->getTimer()->getTime();

		//! Post the left button press event
		dev->postEventFromUser(event);

		//! count the multi-click number ( MultiClick == 1 if it's a double-click; == 2 for triple-click and so on ) -- not sure how to set it right now
		event.MouseInput.MultiClick = dev->getMultiClick(event, clickTime);
		
		//! Post a multi click event if it was a multi click.
		if (event.MouseInput.MultiClick > 0)
		{
		    dev->postEventFromUser(event);
		}
	}
	return 0;
That's the basic idea anyway..

It's probably flawed but I think I can get it working.

I edited this post many times in my haste
Last edited by Ulf on Fri Jul 03, 2009 9:37 am, edited 1 time in total.
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
bitplane
Admin
Posts: 3204
Joined: Mon Mar 28, 2005 3:45 am
Location: England
Contact:

Post by bitplane »

Ulf wrote: But then it will be platform dependent. Can't we establish our own idea. Why does it have to be like Windows or Linux. Especially if they are different to each other.

Why get the operating system default. Let's make our own!
But what about that person with Parkinson's, who set up his operating system's double click speed so he can easily double click. Shouldn't we respect that? It does mean more work by supporting it in all the different devices, but I reckon it's better than ignoring the OS values.

Also I think the Mac idea of multiple clicks is another instance of all n's are equally likely. I can't think of a single example of when you'd need a triple or quadruple click.
Submit bugs/patches to the tracker!
Need help right now? Visit the chat room
Ulf
Posts: 281
Joined: Mon Jun 15, 2009 8:53 am
Location: Australia

Post by Ulf »

Also, why don't we change the EMOUSE_INPUT_EVENT types to irr::u32 ?

It's the same thing in a counting way.

Is enum some benefit over u32 for this case?

In my experimental Extra Mouse Buttons patch for windows I have to do the following:

Code: Select all

event.MouseInput.Event = (irr::EMOUSE_INPUT_EVENT)(irr::EMIE_4MOUSE_PRESSED_DOWN + XButtonModifier);
It's no programming problem, but wouldn't it just be better if it was a plain old int or long?

Here is the whole extra mouse button section for Windows, but just the left mouse "case" is shown.

Code: Select all

#ifdef WM_MOUSELAST
	#undef WM_MOUSELAST
	#define WM_MOUSELAST			0x020D
#endif

#ifndef WM_XBUTTONDOWN
	#define WM_XBUTTONDOWN		0x020B
	#define WM_XBUTTONUP			0x020C
	#define WM_XBUTTONDBLCLK		0x020D
#endif

//! Extra mouse button definitions
/* XButton values are WORD flags */
#ifndef XBUTTON1
	#define XBUTTON1				0x0001
	#define XBUTTON2				0x0002
#endif
/* Were there to be an XBUTTON3, its value would be 0x0004 */
#define XBUTTON3					0x0004
#define XBUTTON4					0x0008
#define XBUTTON5					0x0010

#ifndef GET_XBUTTON_WPARAM
#define GET_XBUTTON_WPARAM(wParam)      (HIWORD(wParam))
#endif

//! Used in WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLICK
/** Note: Stores which extra mouse button was pressed or released by calling (XButton = GET_XBUTTON_WPARAM(wParam)). */
WORD XButton;

//! In X button handling, we set XButtonModifier to be a value that when added to irr::EMIE_4MOUSE_PRESSED_DOWN,
//! will translate to the correct extra mouse button identifier from the enum irr::EMOUSE_INPUT_EVENT.
irr::s32 XButtonModifier = 0;

case WM_XBUTTONDOWN:
	++ClickCount; //! Modified by Ulf
	SetCapture(hWnd);
	event.EventType = irr::EET_MOUSE_INPUT_EVENT;

	//! Determine which extra mouse button was pressed
	XButton = GET_XBUTTON_WPARAM(wParam);

	if (XButton & XBUTTON2)
		XButtonModifier = 1;
	else if (XButton & XBUTTON3)
		XButtonModifier = 2;
	else if (XButton & XBUTTON4)
		XButtonModifier = 3;
	else if (XButton & XBUTTON5)
		XButtonModifier = 4;
	else // if (XButton & XBUTTON1) // else just treat it as first extra mouse button
		XButtonModifier = 0;

	event.MouseInput.Event = (irr::EMOUSE_INPUT_EVENT)(irr::EMIE_4MOUSE_PRESSED_DOWN + XButtonModifier);

        event.MouseInput.X = (short)LOWORD(lParam);
	event.MouseInput.Y = (short)HIWORD(lParam);

	dev = getDeviceFromHWnd(hWnd);
	if (dev)
	{
		//! Get click time as soon as we can.
		clickTime = dev->getTimer()->getTime();

		//! Post the extra button press event
		dev->postEventFromUser(event);

		//! Post a double click event if it was a double click.
		if (dev->isDoubleClick(event, clickTime))
		{
			event.MouseInput.Event = (irr::EMOUSE_INPUT_EVENT)(irr::EMIE_4MOUSE_DOUBLE_CLICKED + XButtonModifier);
			dev->postEventFromUser(event);
		}
	}
	return 0;

That's still using double clicks as multi click is just concept untested... just like this :(

Oh yeah, I had to do this modification for it to make sense

Code: Select all

//! Enumeration for all mouse input events
enum EMOUSE_INPUT_EVENT
{
	//! Left mouse button was pressed down.
	EMIE_LMOUSE_PRESSED_DOWN = 0,

	//! Right mouse button was pressed down.
	EMIE_RMOUSE_PRESSED_DOWN,

	//! Middle mouse button was pressed down.
	EMIE_MMOUSE_PRESSED_DOWN,

	//! 4th mouse button was pressed down.
	EMIE_4MOUSE_PRESSED_DOWN,

	//! 5th mouse button was pressed down.
	EMIE_5MOUSE_PRESSED_DOWN,	

	//! 6th mouse button was pressed down.
	EMIE_6MOUSE_PRESSED_DOWN,	

	//! 7th mouse button was pressed down.
	EMIE_7MOUSE_PRESSED_DOWN,	

	//! 8th mouse button was pressed down.
	EMIE_8MOUSE_PRESSED_DOWN,	

	//! Left mouse button was left up.
	EMIE_LMOUSE_LEFT_UP,

	//! Right mouse button was left up.
	EMIE_RMOUSE_LEFT_UP,

	//! Middle mouse button was left up.
	EMIE_MMOUSE_LEFT_UP,

	//! 4th mouse button was left up.
	EMIE_4MOUSE_LEFT_UP,

	//! 5th mouse button was left up.
	EMIE_5MOUSE_LEFT_UP,	

	//! 6th mouse button was left up.
	EMIE_6MOUSE_LEFT_UP,	

	//! 7th mouse button was left up.
	EMIE_7MOUSE_LEFT_UP,	

	//! 8th mouse button was left up.
	EMIE_8MOUSE_LEFT_UP,

	//! Left mouse button was double-clicked.
	EMIE_LMOUSE_DOUBLE_CLICKED, 

	//! Right mouse button was double-clicked.
	EMIE_RMOUSE_DOUBLE_CLICKED, 

	//! Middle mouse button was double-clicked.
	EMIE_MMOUSE_DOUBLE_CLICKED,

	//! 4th mouse button was double-clicked.
	EMIE_4MOUSE_DOUBLE_CLICKED,	

	//! 5th mouse button was double-clicked.
	EMIE_5MOUSE_DOUBLE_CLICKED,	

	//! 6th mouse button was double-clicked.
	EMIE_6MOUSE_DOUBLE_CLICKED,	

	//! 7th mouse button was double-clicked.
	EMIE_7MOUSE_DOUBLE_CLICKED,

	//! 8th mouse button was double-clicked.
	EMIE_8MOUSE_DOUBLE_CLICKED,	

	//! The mouse cursor changed its position.
	EMIE_MOUSE_MOVED,

	//! The mouse wheel was moved. Use Wheel value in event data to find out
	//! in what direction and how fast.
	EMIE_MOUSE_WHEEL,

	//! No real event. Just for convenience to get number of events
	EMIE_COUNT
};
Last edited by Ulf on Fri Jul 03, 2009 9:42 am, edited 1 time in total.
I can hear birds chirping
:twisted:

I live in the Eye of Insanity.
Post Reply