Avoid: IsActive()
-
Hi there,
I'm wondering, is it possible to avoid
IsActive()
inMessage
to support older C4D-Versions.In another thread: https://developers.maxon.net/forum/topic/11462/understanding-setcommanddragid/4 we've talked about the ability to drag BitmapButtons into the layout via
SetCommandDragId
.def CreateLayout(self): bc = c4d.BaseContainer() bc.SetBool(c4d.BITMAPBUTTON_BUTTON, True) bc.SetInt32(c4d.BITMAPBUTTON_ICONID1, c4d.Ocube) bc.SetInt32(c4d.BITMAPBUTTON_FORCE_SIZE, 32) button = self.AddCustomGui(10003, c4d.CUSTOMGUI_BITMAPBUTTON, "but", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 40, 40, bc) button.SetCommandDragId(c4d.Ocube) return True def Message(self, msg, result): if msg.GetId() == c4d.BFM_INTERACTEND: if self.IsActive(10003): print 'Icon clicked in the GeDialog.'
Is it simply not possible to support older C4D-Versions AND have a draggable BitmapButton...?
Thanks,
Lasse -
Hi @lasselauch, I will take a look, but only in few days since R18 is the minimal version working for IsActive and it's more than 3years old, while we provide support only for 2 previous release.
But maybe there is another way to catch this kind of stuff that would work in older version so that's why I said I will take a look.
Cheers,
Maxime. -
Thanks @m_adam,
for now I've added a workaround for older versions so it's not possible to drag the buttons to the layout.
Works for me, but would be nice to know anyway.
Thanks,
Lasse -
Hi Maxime,
I still have some problems using
IsActive()
. I'm having somec4d.plugins.CommandData
utilizing thec4d.gui.ShowPopupDialog
. Sadly sometimes the Popup will be called even after pressing the button. Happens escpially in the end of the following *.gif. (After clicking on the button, I constantly click on the Menubar, and sometimes the popup will be displayed again...)My
Message(self, msg, result)
looks like the following:def Message(self, msg, result): if c4d.GetC4DVersion() >= 18000: #Handle CommandDragID if msg.GetId() == c4d.BFM_INTERACTEND: if self.IsActive(ids.IDC_BUTTON1): c4d.CallCommand(ids.PLUGIN_ID_EXPORT) elif self.IsActive(ids.IDC_BUTTON2): c4d.CallCommand(ids.PLUGIN_ID_OMCLEANER) elif self.IsActive(ids.IDC_BUTTON3): c4d.CallCommand(ids.PLUGIN_ID_PYSCRIPTS) elif self.IsActive(ids.IDC_BUTTON4): c4d.CallCommand(ids.PLUGIN_ID_RECENTFILES) elif self.IsActive(ids.IDC_BUTTON5): c4d.CallCommand(ids.PLUGIN_ID_CHATLOG) return c4d.gui.GeDialog.Message(self, msg, result)
Any ideas how to avoid or counter-act this!?
Thanks,
Lasse -
May I ask in what range you enumerated your Dialog controls?
If I recall correctly, there was this kind of behavior if the control IDs were below a certain number. -
The
ids
are starting from20001
.IDD_DIALOG = 20001 IDC_BUTTONFLUSHGROUP = 20002 IDC_BUTTON1 = 20003 IDC_BUTTON2 = 20004 IDC_BUTTON3 = 20005 IDC_BUTTON4 = 20006 IDC_BUTTON5 = 20007
Then of course the Commands like
ids.PLUGIN_ID_EXPORT
are generated PluginIDs. -
After looking at your GIF again, it seems like the following happens:
When checking forBFM_INTERACTEND
and poking yround inyour dialog, the focus switches back to the last active Gadget. Thus your commands are fired since you are checking if the gadgets do have the focus. -
Yeah, I guess that makes sense.
What would be the best way to work around that behaviour?Shall I return
return c4d.gui.GeDialog.Message(self, msg, result)
after eachc4d.CallCommand()
?A simple else statement didn't work.
Cheers,
Lasse -
This does not solve your initial issue since it requires the use of GetItemDim and it was introduced in R18 but here is how to avoid your second issue:
import c4d class Dialog(c4d.gui.GeDialog): def CreateLayout(self): bc = c4d.BaseContainer() bc.SetBool(c4d.BITMAPBUTTON_BUTTON, True) bc.SetInt32(c4d.BITMAPBUTTON_ICONID1, c4d.Ocube) bc.SetInt32(c4d.BITMAPBUTTON_FORCE_SIZE, 32) button = self.AddCustomGui(10003, c4d.CUSTOMGUI_BITMAPBUTTON, "but", c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT, 40, 40, bc) button.SetCommandDragId(c4d.Ocube) self.AddStaticText(10001, 0, 0, name="test") return True def IsPositionOnGadget(self, gadgetId, x, y): # Be sure that the windows is opened, # in our case since we call it in BFM_INTERACTSTART it's ok buttonData = self.GetItemDim(gadgetId) if not buttonData["x"] < x < buttonData["x"] + buttonData["w"]: return False if not buttonData["y"] < y < buttonData["y"] + buttonData["h"]: return False return True def Message(self, msg, result): # Main thread if msg.GetId() == c4d.BFM_INTERACTSTART: c4d.StopAllThreads() # Check the mouse is clicked state = c4d.BaseContainer() self.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSERIGHT, state) if state.GetInt32(c4d.BFM_INPUT_CHANNEL) != 0: # Get coordinates x = state.GetInt32(c4d.BFM_INPUT_X) y = state.GetInt32(c4d.BFM_INPUT_Y) g2l = self.Global2Local() x += g2l['x'] y += g2l['y'] # Checks the coordinate is within the range of the BitmapButton if self.IsPositionOnGadget(10003, x, y): print 'Icon clicked in the GeDialog.' # Stop others event to be processed self.KillEvents() return True return c4d.gui.GeDialog.Message(self, msg, result) # Main function def main(): global dlg dlg = Dialog() dlg.Open(c4d.DLG_TYPE_ASYNC) # Execute main() if __name__=='__main__': main()
Note that there is a very similar problem Disable default Right-Click Menu that you may found interesting about how to handle popup in your dialog.
And adding this constraint in mind, I'm afraid I don't see any solution to make it work before R18.
Cheers,
Maxime. -