Hey !... #Sorry_For_My_Bad_English :)
Any easy way to "detect" user double click?
I don't want and im not using any lib etc.
- Pure C++ and Windows
I create my own Engine using C++ ASM and Windows
My "Engine" supports atm:
QKeyboard ( Reference to Keyboard for example )
QKeyboard.Key[ QKeyA ].Push;
( return true if Key "A" is pressed )
and ofc. QMouse
QMouse.Button[ QLeftMouse ].Push
( return true if Left Mouse button is pushed )
to use i have:
- OnPush Event ( takes Void Function )
- OnRelease Event ( takes Void Function )
- PushTime Function ( return Time in seconds )
- ReleaseTime Function ( return Time in seconds )
- Push BOOL Value
QMouse.Button[ QMiddleMouse ].OnPush = MyVoid;
Time = QMouse.ReleaseTime( QRightMouse );
QKeyboard -> Keyboard Data
QMouse -> Mouse Data
QTouch -> Touchpad Data
i have problem with "good" way to detect Double Click...
my actual idea is to register event after user push key
atm. ( at this moment ) i register event after 1 sec
to do ONE CLICK things but if ANOTHER function want
to register this SAME key AGAIN it "clear" register
and do DOUBLE CLICK stuff
but Time Events are atm.... well not very great in my Engine
and it take a lot CPU power to do...
i don't want to waste so much CPU power only for Double Clicks
also my Engine use only CPU
- idk how to use GPU
- my Engine isn't for games anyway
maybe ill make one or two games using it but i want it for AI and Robots
to render GUI CPU is enough :o
GUI ( Graphical User Interface )
CPU ( Central Processing Unit )
WIP ( Work in Progress )
Now... anyone with good idea to handle Double Clicks?...
And again, sorry for my Bad English :)...
reason because Time Events are so bad in my Engine is because
every 0.1 second Engine test every registred event if its time to cast it...
if for example we register 10 Events every 1 seconds we do 100 Tests
if anyone have better idea for this2, plz help :)...
I'll make the assumption that you're using a recent C++ compiler, and that it supports C++17.
The standard library offers good, reasonably high precision timer support. This does depend on the hardware. Many PC's have high precision timers, but some require them to be enabled.
The typical, default configuration for slightly holder hardware is a timer limited to a precision of about 15 ms, which is to say code would sense two events closer in time than 15 ms to be simultaneous, and can't usually report a difference between two events within a 15 ms time boundary. However, that represents a "rate" of about 66 events per second, which is quite fast relative to a user double click time limit.
To implement double event interface on anything (keyboard, mouse, touch, sound, or whatever), one must track the state change on every possible "item". For the keyboard this implies a container representing each key. For keyboard plus mouse, it would be all keys plus the mouse buttons.
As @coder777 noted this also implies, for the mouse, that the second event happens at a location (of the mouse) "near" the previous one, which implies tracking the mouse location at the time of a button press.
Consider my point, that every item must be tracked, in the context of the mouse alone for a moment.
If the buttons were not tracked individually, it would be possible to "accidentally" consider two mouse button events of two different buttons as a double click, which clearly wouldn't be correct.
For some devices, especially of the keyboard, this issue is spread over the entire keyboard.
Further, for some user interface purposes, it is necessary to sense a double event while yet a different key is being held during the entire double click. An obvious potential is that the shift key is held first, then a double click is issued, but for game or other inventive user interface requirements, it could be that an arrow key is held during the double click of the space, or the space is held during the double click of a letter or number.
This suggests a container is required, initialized at startup and used "globally" throughout the application's use of these interface devices, such that an entry is available for each key, each mouse button (and the mouse location at the moment of the event). Rapid lookup is desired, so it is desirable to fashion this as a fixed array such that virtual key codes (supplied by Windows) for keyboard buttons and mouse buttons can be used as unique entries into this array. A map or sorted array by key would require more time for lookup, but would likely be "fast enough" in some cases, but nothing would perform quite as fast as an indexed lookup in an array.
Every attempt to read the keyboard or mouse would thus pass through a function (or collection of functions, perhaps in a class), which records the timestamp of each event. Before it does so, it compares the previous time for that item (be it keyboard or mouse button), and if that is in the past inside the double click time margin (configured as an application level value), it becomes a candidate for a double click on that item (whatever key or mouse button).
Where the type of this entry is a mouse button, a further check should be made, as @coder777 pointed out, that the mouse has not moved beyond a certain margin, also configured as an application value.
This makes the calculation of duration between events rather quick. It requires that every keystroke and mouse button press is timed through timestamp. Perhaps it doesn't require mentioning, but these timed events are focused on the "down" messages, not the "up" messages.
pretty sure windows has a double click detector & you can add a on_double_click() method to a gui program. DIY means watching it over a period of time, as stated, but it should be done for you. Pretty sure any other OS has this too, its just too ingrained to not be part of any gui library...
you need to make a couple of design decisions...
does a key held-down count as 2 clicks, or do they have to let go and hit again.
also do you need to catch it if they were holding it down, let go and hit again rapidly?
I recommend something like
on key up (it was pressed, and now it isnt, for a specific key, not ANY key, of course)
check to see if this was the end of a double tap cycle against your timers.
if so, handle it. (double click detected)
if not, start the timer.
if timer is expired or detected double, stop/clear timer.
the above defines it for down/up down/up as a double click.
adjust as needed if you want to define it differently.