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
Where is the extra work?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.
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;
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;
}
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;
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;
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.
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.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?
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..?
I believe that in Windows a double click posts a click event, then a double click event. Can anyone confirm?Not sure what others would prefer here. Also there's the question if a doubleclick-event is additionally a click-event.
Also that seems to be the general consensus as far as what is wanted or needed. It is still a click after all! Yes?
Great, cause I want to improve it... and I have!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.
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 */
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)
One point.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?
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.