Unsolved Can I use both MouseDown() and DoubleClick() in treeview?

Hi community ,

I want to get both MouseDown() and DoubleClick() in treeview , for example :

  • when I select a item, trigger a change function to update some data.

  • when I doubleclick a item, I want to trigger another function like refresh treeview for some funcs.

But by so far , when I use them both , the trigger will be :

  • MouseDown() => DoubleClick() => MouseDown()

It will call MouseDown twice, how call I aviod this ?

    def MouseDown(self, root, userdata, obj, col, mouseinfo, rightButton):
        print("selection changed")

        return False
    
    def DoubleClick(self, root, userdata, obj, col, mouseinfo):           
        
        print("double click")
        return Ture

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:

  1. Have a _clickQueue: list[float] field which holds a list of the Unix epoch time.time() stamps of the last click(s).
  2. 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.
  3. When a click event occurs append time.time() to _clickQueue and do nothing otherwise.
  4. 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

MAXON SDK Specialist
developers.maxon.net

Hi @ferdinand ,

@ferdinand said in Can I use both MouseDown() and DoubleClick() in treeview?:

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.

That helps foe better unstand how it worked, thanks!

And this kind solution is a much more mature solution than what I used a simple one in my Octane Light Manager, I try to stop the set check event duplicate many times, I will keep more condition as your suggestion.

e0be12a8-f277-400d-9d7a-14065e55ffee-image.png

Thanks again for your detailed explain for all the answer.

Cheers~
DunHou