Hello @Dunhou,
Thank you for reaching out to us and please excuse the short delay, I was fighting yesterday with the forum server and did not get to your posting.
In general, you should keep in mind that the concept of a double click is only represented very weakly in Cinema 4D, with TreeViewFunctions
being one of the very few cases which uses that term. In the backbone of the API, the GUI message stream, the concept of a double click does not exist. Things are actions (BFM_ACTION_...
) and inputs (BFM_INPUT_...
) and each mouse click counts as an input and/or action. It is up to specific gadgets to bundle up multiple clicks into a double click.
Because of that, the reverse does also apply. The core does not hold back a mouse click event until XY milliseconds have elapsed and it can be sure that it is not a double click. To distinguish the first component of a double click from a singular click, you would have to implement that evaluation yourself:
- Have a
_clickQueue: list[float]
field which holds a list of the Unix epoch time.time()
stamps of the last click(s).
- Define a global delta
gd
above which you will no longer consider two consecutive clicks a double click. The value is usually quite high, something like 500 ms. It should of course not be a value lower than what the tree view considers to be a double click.
- When a click event occurs append
time.time()
to _clickQueue
and do nothing otherwise.
- Run a
GeDialog.Timer
on the dialog holding the tree view with a tick frequency that is lower than gd
and ideally half its length. But remember that below 100 ms
timers become quite imprecise. With it, you evaluate your _clickQueue
:
- Get the current time
t
.
- When there are two or more items in the queue, and the delta
d
between the first item and t
is below gd
, a double click has occurred. Carry out the double click action and flush the queue.
- When there is only one item in the queue and the delta
d
between that item and t
is larger than gd
, a single click has occured. Crarry out the single click action and flush the queue.
In practice this can be a bit more complicated as you must deal with edges cases of the queue being filled up in a "tricky" manner in relation to your timer ticks. So, something like this can happen:
gd: x---x
clicks : --a---b--c---
eval : -1---2---3---
The first two clicks a
and b
do not form a double click because they are gd
units apart, but b
and c
do because they are closer. But you do yet know that on the tick event 2
because you are there still one bar short of your global cutoff delta, you cannot yet say that a
is a single click. So, you can end up with multiple events in your queue. I did not unpack all that in my brief bullet points above. This is also why you want to eval
to fit multiple times into gd
when possible.
Cheers,
Ferdinand