right click menu?



  • On 09/09/2014 at 10:23, xxxxxxxx wrote:

    Is it possible to create a list of "items" that I could right click on and have a custom menu popup inline?

    Essentially they way I'd like to it work is have a text box auto fill with a list and then be able to right click on individual items in the list to bring up a custom menu.



  • On 09/09/2014 at 10:28, xxxxxxxx wrote:

    Duh, found it:
    https://plugincafe.maxon.net/topic/7621/9561_right-click-in-dialog



  • On 09/09/2014 at 10:41, xxxxxxxx wrote:

    Well, maybe I spoke too soon. I can't get this to work :( Here's the code I'm using:

      
    class PositionCloner(c4d.plugins.CommandData) :   
      
        dialog = None   
      
        def Init(self, op) :   
            return True   
      
        def Message(self, msg, result) :   
            if msg.GetId() == c4d.BFM_INPUT:   
                if msg.GetLong(c4d.BFM_INPUT_CHANNEL)==c4d.BFM_INPUT_MOUSERIGHT:   
                        
                   # put in your code which will be executed on right mouse click   
                   menu = c4d.BaseContainer()   
                   menu.SetString(1000, 'Item 1')   
                   menu.SetString(1001, 'Item 2')   
                   menu.SetString(0, "")               # Append separator   
                   menu.SetString(1003, 'Item 2')   
                        
                   result = c4d.gui.ShowPopupDialog(cd=None, bc=menu, x=c4d.MOUSEPOS, y=c4d.MOUSEPOS)   
                        
                        
                   return True # don't route message to window parents   
                   
            return c4d.gui.GeDialog.Message(self, msg, msg)   
      
        def Execute(self, doc) :   
            if self.dialog is None:   
                self.dialog = PositionClonerDialog()   
            return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=400, defaulth=160)   
      
    if __name__ == '__main__':   
        bmp = c4d.bitmaps.BaseBitmap()   
        dir, file = os.path.split(__file__)   
        fn = os.path.join(dir, "res", "Icon.tif")   
        bmp.InitWith(fn)   
        print "Position Cloner loaded."   
        result = plugins.RegisterCommandPlugin(PLUGIN_ID, "PositionCloner", 0, bmp, "PositionCloner", PositionCloner())
    


  • On 09/09/2014 at 11:23, xxxxxxxx wrote:

    That code is for a GeDialog. But you're using it in a CommandData class.
    The CommandData class is only used to give you a way to launch the GeDialog from the menu. So you need to write your gizmo code for a GeDialog class.

    Put this code in your script manager and run it.
    Then RMB click in the dialog and select an item from the popup list. And it will put what you selected in the textbox.
    This is a script example. But works the same way in plugins.

    import c4d  
    from c4d import gui  
      
    class CustomDialog(c4d.gui.GeDialog) :  
      
      def CreateLayout(self) :  
          self.AddEditText(2222, c4d.BFH_CENTER, initw=120, inith=15)  
          return True  
        
      def Message(self, msg, result) :  
      
          if msg.GetId() == c4d.BFM_INPUT:  
               if msg.GetLong(c4d.BFM_INPUT_CHANNEL)==c4d.BFM_INPUT_MOUSERIGHT:  
                     
                   #Put in your code which will be executed upon a RMB click  
                   entries = c4d.BaseContainer()  
                   entries.SetString(1000, 'Item 1')  
                   entries.SetString(1001, 'Item 2')  
                   entries.SetString(0, "")             #Using a 0 Adds a separator  
                   entries.SetString(1003, 'Item 3')  
                     
                   popupGizmo = c4d.gui.ShowPopupDialog(cd=None, bc=entries, x=c4d.MOUSEPOS, y=c4d.MOUSEPOS)                   
                   popupText = entries.GetString(popupGizmo)  
                   self.SetString(2222, popupText)  
                
          return c4d.gui.GeDialog.Message(self, msg, msg)      
      
    def main() :  
      myDialog = CustomDialog()  
      myDialog.Open(dlgtype=c4d.DLG_TYPE_MODAL_RESIZEABLE, pluginid=1000001, defaultw=150, defaulth=100, xpos=-1, ypos=-1)  
        
    if __name__=='__main__':  
      main()
    

    -ScottA



  • On 09/09/2014 at 11:25, xxxxxxxx wrote:

    Sweet!!! That'll help start me down the path! Thanks again!



  • On 09/09/2014 at 22:41, xxxxxxxx wrote:

    So how would I incorporate this into a plugin?

    Here's what I have so far, but I just keep getting the default c4d right click menu:

      
    import c4d   
    from c4d import plugins   
    import os   
      
    class PipelineDialog(c4d.gui.GeDialog) :   
      
        def CreateLayout(self) :   
            self.SetTitle("c4d Pipeline")   
            self.AddEditText(2222, c4d.BFH_CENTER, initw=120, inith=15)   
      
    class Pipeline(c4d.plugins.CommandData) :   
      
        dialog = None   
      
        def Init(self, op) :   
            return True   
      
        def Message(self, type, data) :   
            return True   
      
        def Execute(self, doc) :   
            if self.dialog is None:   
                self.dialog = PipelineDialog()   
            return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaultw=400, defaulth=160)   
      
    if __name__ == '__main__':   
        bmp = c4d.bitmaps.BaseBitmap()   
        dir, file = os.path.split(__file__)   
        fn = os.path.join(dir, "res", "Icon.tif")   
        bmp.InitWith(fn)   
        print "Position Cloner loaded."   
        result = plugins.RegisterCommandPlugin(PLUGIN_ID, "c4d pipeline_part", 0, bmp, "c4d pipeline", Pipeline())   
    


  • On 10/09/2014 at 08:52, xxxxxxxx wrote:

    Hmmm. That's a good question.
    I can't find anywhere in the SDK how to tell C4D to shut off the RMB stuff.
    Normally these popups are used in Tool plugins and this is not an issue.

    I'm not sure if it's possible to use the RMB with a GeDialog.
    You might have to use a keyboard key instead. Or possibly a qualifier key with the RMB.
    It's an annoying limitation for sure.

    -ScottA



  • On 10/09/2014 at 10:27, xxxxxxxx wrote:

    Well, what I think might work instead is to have a select box with a series of buttons beneath. Essentially "buttonizing" the menu beneath. I only have a few functions that I need.    Is there a way to create something similar to this?

    http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_select_multiple

    I'm originally an HTML guy so I usually think of things from that angle.   Just FYI I'm trying to create an asset manager similar to this: http://openpipeline.cc/

    So all I would need is a list of files where one could be selected so I can perform my actions on the selected list item. Is there a way to make selectable list items like that?



  • On 10/09/2014 at 11:27, xxxxxxxx wrote:

    That's a linkbox gizmo.
    In C4D it's called this: CUSTOMGUI_LINKBOX

    This gizmo is not available in the Python SDK. Only in the C++ SDK.
    I know how to create the gizmo itself. But the functions for populating it are not available in the Python version of the SDK. Or at least AFAIK.

    NiklasR. wrote a gizmo like this using the UserArea class.
    I can't remember off hand where it is. But you might find it by searching the archives. Or by contacting him directly.

    -ScottA



  • On 10/09/2014 at 11:57, xxxxxxxx wrote:

    Oh BTW:
    There does seem to be one way to shut off the RMB click thing.
    And that's to make the GeDialog modal.

      
    return self.dialog.Open(dlgtype=c4d.DLG_TYPE_MODAL, pluginid=PLUGIN_ID, defaultw=200, defaulth=150, xpos=-1, ypos=-1)
    

    Of course the down side of this is that the user has to close the dialog before they can do anything in the scene. And they won't be able to dock the dialog in the UI.
    But if that's not a deal breaker. Then using a modal dialog should work.

    -ScottA



  • On 06/10/2014 at 09:44, xxxxxxxx wrote:

    I've been playing around with this some more and have discovered that you I can't detect any type of click in an ASYNC dialog. Is there no way to detect a click at all using ASYNC?



  • On 06/10/2014 at 09:48, xxxxxxxx wrote:

    I found this and think it might be able to solve the problem but have no idea how to implement it. Any suggestions?
    http://www.maxonexchange.de/sdk/CINEMA4DPYTHONSDK/help/misc/inputevents.html



  • On 06/10/2014 at 10:41, xxxxxxxx wrote:

    I figured it out!!!

    Turns out ASYNC only runs along with script execution, so if you need to continually poll the input you need to run it as a command plugin NOT a script. From my understanding a script is only listening to input as its running, but a plugin is continually listening for input while the dialog is open. I figured I could just build as a script and then port over to a plugin format, but that is NOT the case.

    https://plugincafe.maxon.net/topic/6134/6370_py-scriptmng--geuserarea-disappears


Log in to reply