Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Recent
    • Tags
    • Users
    • Login

    Two mouse releases

    Scheduled Pinned Locked Moved PYTHON Development
    9 Posts 0 Posters 684 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H Offline
      Helper
      last edited by

      On 12/04/2014 at 05:56, xxxxxxxx wrote:

      I have a SplineControl CustomGui in a dialog and it is working fine.
      Now I want to react when the spline is changed. Thus when a knot position or tangent has changed.
      What I want to do is to react on the mouse release after a splinecontrol event.
      Everything is ok, except I receive 2 releases?

      I am wondering why I "receive" 2 releases?

          def Command(self, id, msg) :
              if (id == MY_SPLINE) :
                  bc = c4d.BaseContainer()
                  if self.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSELEFT, bc) :
                      if not bc.GetBool(c4d.BFM_INPUT_VALUE) : 
                          print "Left mouse released. Start processing."
        
      
      
      1 Reply Last reply Reply Quote 0
      • H Offline
        Helper
        last edited by

        On 12/04/2014 at 06:37, xxxxxxxx wrote:

        Adding some extra information.

        I want to check for the release of the left mouse, because the release indicates the end of a drag of a knot or a tangent. Just acting on a command id is thus not enough. I must combine it with the end of the drag == the release of the mouse.

        The problem is that I detect two release and in my opinion there should only be one release?

        Of course, I can solve it be checking for the second release, but I rather like to know why I receive 2 releses?

        1 Reply Last reply Reply Quote 0
        • H Offline
          Helper
          last edited by

          On 12/04/2014 at 09:15, xxxxxxxx wrote:

          The Command() method makes things fire (checkbox, buttons, etc..) when you LMB click in the GUI.
          It fires when your mouse is down and hasn't been released yet. Using the ID# of the gizmo.
          I'm guessing that it's returning once for the "Yes..I've found the ID# successfully." event.
          And once for the actual mouse down event.
          That's just a wild guess though.

          The only way to check for a mouse up state in C4D is with a while loop.
          The two most common places they are used is in the MouseInput() method. Or the Message() method.
          For a GeDialog it's used in the Message() method:

              def Message(self, msg, result) :  
             
                if msg.GetLong(c4d.BFM_INPUT_CHANNEL)==c4d.BFM_INPUT_MOUSELEFT:  
                    print "Begin Mouse Left Pressed"  
            
                    while True:  
                        bc = c4d.BaseContainer()  
                        if gui.GetInputState(c4d.BFM_INPUT_MOUSE, c4d.BFM_INPUT_MOUSELEFT, bc) :  
                            if bc.GetLong(c4d.BFM_INPUT_CHANNEL)==c4d.BFM_INPUT_MOUSELEFT:  
                                print "LMB is being Pressed"  
                                if not bc.GetBool(c4d.BFM_INPUT_VALUE) : break  
            
                    print "LMB Was Released"          
                     
                return gui.GeDialog.Message(self, msg, result)
          

          -ScottA

          1 Reply Last reply Reply Quote 0
          • H Offline
            Helper
            last edited by

            On 13/04/2014 at 07:02, xxxxxxxx wrote:

            Sound logical. I 'll use your method in the Message().
            -Pim

            1 Reply Last reply Reply Quote 0
            • H Offline
              Helper
              last edited by

              On 14/04/2014 at 00:51, xxxxxxxx wrote:

              Sorry, I switched to C++ (in order to test "Show in separate window").

              I keep getting 2 releases in Command().
              Even if I check the state of the LMB.

              Note: I'm doing the checking in Command(), not in Message().
              I am using a command plugin.

              Also checking the LMB for release, dragging is no longer working.

              Bool MyDialog::Command(Int32 id,const BaseContainer &msg)
              {	
              	Int32 i;
              	Vector vector;
              	BaseContainer bc;
                  switch (id) 
                  {
              		case MY_SPLINE:		
              		{
              			//if (msg.GetInt32(BFM_INPUT_CHANNEL) == BFM_INPUT_MOUSELEFT)
              			if (GetInputState(BFM_INPUT_MOUSE, BFM_INPUT_MOUSELEFT, bc))
              			{
              				GePrint ("Begin Mouse Left Pressed");
                
              				while (true)
              				{
              					GetInputState(BFM_INPUT_MOUSE, BFM_INPUT_MOUSELEFT, bc);
              						if (bc.GetInt32(BFM_INPUT_CHANNEL) == BFM_INPUT_MOUSELEFT)
              						{
              							GePrint ("LMB is being Pressed");
              							if (!bc.GetBool(BFM_INPUT_VALUE)) break;
              						}
              				}
              				GePrint ("LMB Was Released");
              			}
                
                
              			GePrint ("MY_SPLINE processing.");
                
              
              

              This is what I see in the console when pressing once in the spline gui dialog.:

              1 Reply Last reply Reply Quote 0
              • H Offline
                Helper
                last edited by

                On 14/04/2014 at 07:58, xxxxxxxx wrote:

                Originally posted by xxxxxxxx

                I am using a command plugin.

                I'm confused.

                A command plugin (CommandData plugin) does not have a dialog in it.
                It is the plugin equivalent to running a script when clicking in the plugins menu.

                If you're using a dialog in your plugin. Then it's clearer to say that the type of plugin you are working on is a "GeDialog" plugin. Not a "command plugin".
                We all know that a CommandData plugin is required to launch the GeDialog part of the plugin.
                So it's more clear to just say "GeDialog plugin" when working with dialogs...and "CommandData plugin" when not using any dialogs.

                The mouse looks like it's working as expected to me.
                But the Command() method is not the correct place to use it.

                -ScottA

                EDIT - Oh Shoot.
                I forgot that we are not allowed to run that kind of mouse up code in a GeDialog()
                It works fine in a tool plugin. But a while loop like that used in the Message() method of a GeDialog plugin will lock it up.
                Sorry about that. 😊

                I think you'll have better success if you instead focus on trying to see if the gizmo has changed or not to send your event. Rather than checking for a mouse up event.

                1 Reply Last reply Reply Quote 0
                • H Offline
                  Helper
                  last edited by

                  On 14/04/2014 at 10:23, xxxxxxxx wrote:

                  Here's another possible idea that might do what you need:

                  class MyDialog : public GeDialog  
                  {  
                    private:  
                    MyDialog *dlg;  
                    Bool mValue;     //<--The state of the LMB  
                    
                    public:  
                        MyDialog(void);  
                       ~MyDialog(void);  
                        virtual Bool CreateLayout(void);  
                        //etc....      
                  };  
                    
                  LONG MyDialog::Message(const BaseContainer &msg, BaseContainer &result)  
                  {  
                    //Save the state of the LMB in a class level variable  
                    //That way we can use it in the Command() method  
                    BaseContainer bc;  
                    GetInputState(BFM_INPUT_MOUSE, BFM_INPUT_MOUSELEFT, bc);  
                    if(bc.GetData(BFM_INPUT_VALUE)==TRUE) mValue = TRUE;  
                    else mValue = FALSE;  
                    
                    return GeDialog::Message(msg,result);  
                  }  
                    
                    
                  Bool MyDialog::Command(LONG id,const BaseContainer &msg)  //This is where the code that does something goes  
                  {  
                      
                    switch(id)   
                      {  
                      case MY_GIZMO:  
                          {               
                              if(mValue) Do something in the dialog here....;              
                          }  
                          break;  
                    
                      }  
                    
                    EventAdd();  
                    return TRUE;  
                  }
                  

                  -ScottA

                  1 Reply Last reply Reply Quote 0
                  • H Offline
                    Helper
                    last edited by

                    On 15/04/2014 at 10:12, xxxxxxxx wrote:

                    Originally posted by xxxxxxxx

                    EDIT - Oh Shoot.
                    I forgot that we are not allowed to run that kind of mouse up code in a GeDialog()
                    It works fine in a tool plugin. But a while loop like that used in the Message() method of a GeDialog plugin will lock it up.

                    Thanks, that explains. I'll try a tool plugin.
                    And yes, it is a Commandplugin with a dialog.
                    This is what I use (high level).

                    class MyDialog : public GeDialog
                    {
                        private:
                    	SplineCustomGui* m_spline;
                        public :
                            virtual Bool CreateLayout(void);
                    	virtual Bool InitValues(void);
                            virtual Bool Command(Int32 id,const BaseContainer &msg);
                    	virtual Int32 Message(const BaseContainer &msg, BaseContainer &result);
                    };
                      
                      
                    Bool MyDialog::CreateLayout()
                      
                    Bool MyDialog::InitValues(void)
                      
                    Bool MyDialog::Command(Int32 id,const BaseContainer &msg)
                      
                    class SplineControlCpp : public CommandData
                    {
                        public:
                            virtual Bool Execute(BaseDocument *doc);
                    };
                      
                    Bool SplineControlCpp::Execute(BaseDocument *doc)
                    {   
                        if(dlg) DeleteObj(dlg);
                        dlg = NewObjClear(MyDialog);
                    	dlg->Open(DLG_TYPE_ASYNC,PLUGIN_ID,-1,-1,200,300);
                    	
                        return TRUE;
                    }
                      
                    Bool RegisterSplineControlCpp(void)
                    {     
                        return RegisterCommandPlugin(PLUGIN_ID,String("SplineControl Cpp ...
                      
                    
                    

                    I am implementing your latest tip. 
                    Thanks, Pim

                    1 Reply Last reply Reply Quote 0
                    • H Offline
                      Helper
                      last edited by

                      On 15/04/2014 at 13:30, xxxxxxxx wrote:

                      Ok. Sorry again for the mixup.
                      When I don't work with them for a while. I tend to forget how different GeDialogs are compared to the other plugins.

                      There are lots of special proprietary things in the SDK just for dealing with the gizmos in them. Which begin with "BFM_" in the docs.
                      Those BFM's can often be used for mousing events. Like letting you know if a slider is being dragged..stuff like that.
                      If you ever get stuck trying to do something with a GeDialog. Those BFM's are probably the best place to look first, before trying to invent your own custom solutions like I did.
                      I tend forget about them myself.

                      I did write a C++ GeDialog plugin example a while ago that has a spline GUI in it. Which also has a SplineDataCallback in it that returns the mouse's X&Y positions in it.
                      If that's something you think you'd need. Send me a message with your e-mail and I'll zip it up and send it to you.

                      -ScottA

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post