Getting a GadgetID during BFM_INTERACTSTART
-
Hello,
I'd like to detect when an EditSlider gadget in my GeDialog is first being dragged. I am overriding the Message function and listening forc4d.BFM_INTERACTSTART
so I can see which Gadget sent the Message. A strange thing occurs though: when I try to print the msg and result BaseContainers, neither return any values.I can check if the EditSlider is active using GeDialog.IsActive(), but it fires with every
c4d.BFM_INTERACTSTART
Message, which is undesired.Is there a way to detect the GadgetID from the
c4d.BFM_INTERACTSTART
Message?Here is code demonstrating my issue:
import c4d from c4d import gui PLUGIN_ID=1972142 GROUP_ID1=1000 SLIDER=1001 class MyDlg(gui.GeDialog): def CreateLayout(self): self.SetTitle("Interact Start Demo") if self.GroupBegin(GROUP_ID1, c4d.BFH_SCALEFIT, 1, 1): self.GroupBorderSpace(20,20,20,20) self.AddEditSlider(SLIDER, c4d.BFH_SCALEFIT | c4d.BFV_CENTER, initw=0, inith=0) self.GroupEnd() return True def InitValues(self): self.SetFloat(SLIDER, value=50, min=0, max=100, step=1) return True def Message(self, msg, result): if msg.GetId() == c4d.BFM_INTERACTSTART: print "*"*100 #Can I get the Gadget ID from this Message? for cid,value in msg: print "MSG id: %s, value: %s"%(cid,value) #doesn't print for cid,value in result: print "RESULT id: %s, value: %s"%(cid,value) #doesn't print print "slider active: %s"%self.IsActive(SLIDER) #Can't use as is because it fires True with every interaction where the slider is active (not just dragging the slider). return c4d.gui.GeDialog.Message(self, msg, result) c4d.CallCommand(12305) # Console global dlg dlg = MyDlg() dlg.Open(c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=300, defaulth=100, xpos=-2, ypos=-2)
Thank you!
-
Hi,
I do not think that you can get the id. The reason that your code does not print anything, is because you treat the message id and data containers like iterables for a loop. Which in turn will not do anything when said containers are empty.
Is there a specific reason why you do not (want to) use
GeDialog.Command
? It has a specific message for drag events of sliders (BFM_ACTION_INDRAG
).Cheers,
zipit -
Hi @zipit , thank you for your reply. I am treating the message & data containers as iterables because they are both BaseContainers and I don't know which IDs they contain. If the containers are empty, where is msg.GetId() getting its data? Is the ID separate from the msg BaseContainer's data?
I have something working with
BFM_ACTION_INDRAG
but it is not very elegant as the drag ID is executed many times during a drag. As mentioned in the original post, I am interested in executing code only once on the initial touch of the slider.This is what I'm doing:
import c4d from c4d import gui PLUGIN_ID=1972142 GROUP_ID1=1000 SLIDER=1001 class MyDlg(gui.GeDialog): def __init__(self): self.firstInteraction = False def CreateLayout(self): self.SetTitle("Interact Start Demo") if self.GroupBegin(GROUP_ID1, c4d.BFH_SCALEFIT, 1, 1): self.GroupBorderSpace(20,20,20,20) self.AddEditSlider(SLIDER, c4d.BFH_SCALEFIT | c4d.BFV_CENTER, initw=0, inith=0) self.GroupEnd() return True def InitValues(self): self.SetFloat(SLIDER, value=50, min=0, max=100, step=1) return True def Command(self,id,msg): if id == SLIDER: if self.firstInteraction == False: if msg[c4d.BFM_ACTION_INDRAG] == 1: if self.firstInteraction == False: print "first interaction" # first interaction code goes here self.firstInteraction = True if msg[c4d.BFM_ACTION_INDRAG] == None: self.firstInteraction = False return True c4d.CallCommand(12305) # Console global dlg dlg = MyDlg() dlg.Open(c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=300, defaulth=100, xpos=-2, ypos=-2)
Do you or anyone else have any thoughts on this implementation? Thank you!
-
Hi,
@blastframe said in Getting a GadgetID during BFM_INTERACTSTART:
If the containers are empty, where is msg.GetId() getting its data? Is the ID separate from the msg BaseContainer's data?
yes, the id of a container is separate from its data. It is just an easy to access integer attached to the container which is used to tell the recipient something about the purpose of the container. What you are effectively doing is something like this:
data = [] #Will not do anything since the iterator of data will never yield anything. for item in data: print item
I have something working with
BFM_ACTION_INDRAG
but it is not very elegant as the drag ID is executed many times during a drag [...]Aside from the crazy amount of branching I do not see anything inherently inelegant about your code. Do you have any specific concerns? Without that any suggestions for "improvement" would be highly subjective.
Cheers,
zipit -
hi,
I don't see what's wrong neither. Using a boolean to know if your function have been already execute once is pretty common.
As long as you got what you need.Cheers,
Manuel -
Thank you both! @zipit & @m_magalhaes