Solved Avoid: IsActive()

Hi there,

I'm wondering, is it possible to avoid IsActive() in Message to support older C4D-Versions.

In another thread: https://plugincafe.maxon.net/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 some c4d.plugins.CommandData utilizing the c4d.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...)

2020-04-07_09-36-59.gif

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 from 20001.

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 for BFM_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 each c4d.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.

Thanks @m_adam for the insights!

Works like a charm!!

Cheers,
Lasse