[SOLVED] Bug: incorrect double click events

scrawl

29-01-2014 16:36:24

Observed in MyGUI SVN.

To reproduce this issue, create a ListBox with 2 items and register the eventListSelectAccept event (that gets called for double click or enter key).
Next, you click on the first item, then (fast) click on the second item.
Result: first item gets selected, then second item gets accepted.
Expected result: first item gets selected, then second item gets selected.

Double clicks should only trigger if you click on the same item twice.

scrawl

29-01-2014 17:06:48

Please find attached my patch for the bug. This resets the double click timer when the mouse focus changes.


Index: MyGUIEngine/include/MyGUI_InputManager.h
===================================================================
--- MyGUIEngine/include/MyGUI_InputManager.h (revision 5292)
+++ MyGUIEngine/include/MyGUI_InputManager.h (working copy)
@@ -148,7 +148,8 @@
ILayer* mLayerMouseFocus;

// таймер для двойного клика
- Timer mTimer; //used for double click timing
+ //used for double click timing
+ float mTimerDoubleClick; // time since the last click

// нажат ли шифт
bool mIsShiftPressed;
Index: MyGUIEngine/src/MyGUI_InputManager.cpp
===================================================================
--- MyGUIEngine/src/MyGUI_InputManager.cpp (revision 5292)
+++ MyGUIEngine/src/MyGUI_InputManager.cpp (working copy)
@@ -33,7 +33,8 @@
mFirstPressKey(false),
mTimerKey(0.0f),
mOldAbsZ(0),
- mIsInitialise(false)
+ mIsInitialise(false),
+ mTimerDoubleClick(INPUT_TIME_DOUBLE_CLICK)
{
resetMouseCaptureWidget();
}
@@ -206,7 +207,11 @@
mWidgetMouseFocus = item;

if (old_mouse_focus != mWidgetMouseFocus)
+ {
+ // Reset double click timer, double clicks should only work when clicking on the *same* item twice
+ mTimerDoubleClick = INPUT_TIME_DOUBLE_CLICK;
eventChangeMouseFocus(mWidgetMouseFocus);
+ }

return isFocusMouse();
}
@@ -309,7 +314,7 @@
{
if (MouseButton::Left == _id)
{
- if (mTimer.getMilliseconds() < INPUT_TIME_DOUBLE_CLICK)
+ if (mTimerDoubleClick < INPUT_TIME_DOUBLE_CLICK)
{
mWidgetMouseFocus->_riseMouseButtonClick();
// после вызова, виджет может быть сброшен
@@ -324,7 +329,7 @@
{
mWidgetMouseFocus->_riseMouseButtonClick();
}
- mTimer.reset();
+ mTimerDoubleClick = 0;
}
}
}
@@ -558,6 +563,7 @@
}

mTimerKey += _frame;
+ mTimerDoubleClick += _frame;

if (mFirstPressKey)
{

Altren

17-02-2014 13:54:11

It seems, that there is something wrong with INPUT_TIME_DOUBLE_CLICK - it have time delay in miliseconds, while you measure time with float in mTimerDoubleClick and also I don't understand why you replaced timer with this float.

scrawl

17-02-2014 14:30:13


It seems, that there is something wrong with INPUT_TIME_DOUBLE_CLICK - it have time delay in miliseconds

Oops! Fixed.

I don't understand why you replaced timer with this float.
Because there needs to be a way to set it to a specific time. See this line:

mTimerDoubleClick = INPUT_TIME_DOUBLE_CLICK;

The Timer class only supports resetting to zero.

There was another issue with the first patch: in frameEntered mTimerDoubleClick must be incremented even when there is no key focus.

It should be all good now. Here is version 2:

Index: MyGUIEngine/include/MyGUI_InputManager.h
===================================================================
--- MyGUIEngine/include/MyGUI_InputManager.h (revision 5292)
+++ MyGUIEngine/include/MyGUI_InputManager.h (working copy)
@@ -148,7 +148,8 @@
ILayer* mLayerMouseFocus;

// таймер для двойного клика
- Timer mTimer; //used for double click timing
+ //used for double click timing
+ float mTimerDoubleClick; // time since the last click

// нажат ли шифт
bool mIsShiftPressed;
Index: MyGUIEngine/src/MyGUI_InputManager.cpp
===================================================================
--- MyGUIEngine/src/MyGUI_InputManager.cpp (revision 5292)
+++ MyGUIEngine/src/MyGUI_InputManager.cpp (working copy)
@@ -14,8 +14,8 @@

namespace MyGUI
{
-
- const unsigned long INPUT_TIME_DOUBLE_CLICK = 250; //measured in milliseconds
+ // In seconds
+ const float INPUT_TIME_DOUBLE_CLICK = 0.25f;
const float INPUT_DELAY_FIRST_KEY = 0.4f;
const float INPUT_INTERVAL_KEY = 0.05f;

@@ -33,7 +33,8 @@
mFirstPressKey(false),
mTimerKey(0.0f),
mOldAbsZ(0),
- mIsInitialise(false)
+ mIsInitialise(false),
+ mTimerDoubleClick(INPUT_TIME_DOUBLE_CLICK)
{
resetMouseCaptureWidget();
}
@@ -206,7 +207,11 @@
mWidgetMouseFocus = item;

if (old_mouse_focus != mWidgetMouseFocus)
+ {
+ // Reset double click timer, double clicks should only work when clicking on the *same* item twice
+ mTimerDoubleClick = INPUT_TIME_DOUBLE_CLICK;
eventChangeMouseFocus(mWidgetMouseFocus);
+ }

return isFocusMouse();
}
@@ -309,7 +314,7 @@
{
if (MouseButton::Left == _id)
{
- if (mTimer.getMilliseconds() < INPUT_TIME_DOUBLE_CLICK)
+ if (mTimerDoubleClick < INPUT_TIME_DOUBLE_CLICK)
{
mWidgetMouseFocus->_riseMouseButtonClick();
// после вызова, виджет может быть сброшен
@@ -324,7 +329,7 @@
{
mWidgetMouseFocus->_riseMouseButtonClick();
}
- mTimer.reset();
+ mTimerDoubleClick = 0;
}
}
}
@@ -547,6 +552,8 @@

void InputManager::frameEntered(float _frame)
{
+ mTimerDoubleClick += _frame;
+
if ( mHoldKey == KeyCode::None)
return;

Altren

17-02-2014 16:53:02

Patch applied. Thank you.

scrawl

17-02-2014 16:56:10

Great :)