Two mouse releases



  • 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."
      
    
    


  • 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?



  • 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



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

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



  • 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.:



  • 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.



  • 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



  • 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



  • 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


Log in to reply