GeUserArea keyboard focus



  • On 23/08/2015 at 01:52, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   15+ 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    I can't get focus properly on keyboard, somehow to get focus I need to do a click first with mouse, then it can read keyboard ONCE!!, I need it to get the keyboard keys anytime "not just once, or by a refreshing mouse click"

      
    Bool SNodeUserArea::InputEvent(const BaseContainer& msg)
    {
    	Int32 dev = msg.GetInt32(BFM_INPUT_DEVICE);
    	Int32 chn = msg.GetInt32(BFM_INPUT_CHANNEL);
      
    	if (dev == BFM_INPUT_KEYBOARD)
    	{
    		GePrint("key pressed");//prints only if I press mouse before keyboard...
    		if(chn == KEY_DELETE)
    		{			
    			BaseContainer actionk(BFM_ACTION);
    			actionk.SetInt32(BFM_ACTION_ID, GetId());
    			actionk.SetInt32(BFM_ACTION_VALUE, 0);
    			actionk.SetInt32(BFM_ACTION_UPDATE, true);
    			
    			removeSelectedNodes();
    			removeSelectedWires();
    			InvokeCommandCall(GetDialog(), COMMANDMSG_VALUECHANGED);
    			SendParentMessage(actionk);
    			return true;
    		}
    	}
    	else if (dev == BFM_INPUT_MOUSE)
    	{  
                ...  
            }  
            return false;  
    }  
    


  • On 24/08/2015 at 01:59, xxxxxxxx wrote:

    Hello,

    what exactly are you doing in InvokeCommandCall() and what consequences does SendParentMessage() have? Do you also loose the focus if you don't call InvokeCommandCall()?

    Best wishes,
    Sebastian



  • On 24/08/2015 at 02:27, xxxxxxxx wrote:

    here is what I do:

      
    static Bool InvokeCommandCall(GeDialog* dialog, Int32 id) {
        BaseContainer actionmsg(BFM_ACTION), actionresult;
        actionmsg.SetInt32(BFM_ACTION_ID, id);
        return dialog->Message(actionmsg, actionresult);
    }  
    

    in iCustomGui subclass:

      
        virtual Bool Command(Int32 id, const BaseContainer& msg) {
            if (id == COMMANDMSG_VALUECHANGED) {
                SendValueChanged(this, msg);
            }
            return TRUE;
        }  
    
      
    static Bool SendValueChanged(iCustomGui* dlg, BaseContainer msg) {
        msg.SetInt32(BFM_ACTION_ID, dlg->GetId());
        msg.RemoveData(BFM_ACTION_VALUE);	
        msg.SetData(BFM_ACTION_VALUE, dlg->GetData().GetValue());
        //GePrint("just msg " + String::IntToString((static_cast<iSnodeDataType*> (msg.GetData(BFM_ACTION_VALUE).GetCustomDataType(SEVENPHOTONS_NODE_CUSTOMDATATYPE)))->count));
    	return dlg->SendParentMessage(msg);
    }  
    

    which is simply updating my CustomDataType members, so if user interacts with GeUserArea,  InvokeCommandCall()  is the update function.

    if I remove  InvokeCommandCall()  , there is a delay, but it works without a problem, what should I do?



  • On 24/08/2015 at 09:13, xxxxxxxx wrote:

    Hello,

    why are you sending a message in InvokeCommandCall() and then again with SendParentMessage()? Typically one uses SendParentMessage() to inform the parent dialog that something changed.  See the example on GitHub.

    Best wishes,
    Sebastian



  • On 24/08/2015 at 10:39, xxxxxxxx wrote:

    I see, but the problem remains "I removed all calls to SendParentMessage(), all calls now are InvokeCommandCall()"



  • On 25/08/2015 at 00:07, xxxxxxxx wrote:

    Hello,

    actually I would have suggested to remove that InvokeCommandCall() stuff and just send the SendParentMessage() to react accordingly when you catch that message.

    Best wishes,
    Sebastian



  • On 25/08/2015 at 04:18, xxxxxxxx wrote:

    I will try, will reply soon with an update if it worked or not, thanks Sebastian.



  • On 28/12/2015 at 18:39, xxxxxxxx wrote:

    Hi Sebastian,
    I know that was a little old, but I reworked the code and did many tests to see where the problem is.
    now what I can confirm: (attached a piece of the code..)

      
    Bool SNodeUserArea::InputEvent(const BaseContainer& msg)
    {
    	Int32 dev = msg.GetInt32(BFM_INPUT_DEVICE);
    	Int32 chn = msg.GetInt32(BFM_INPUT_CHANNEL);
    	GePrint("any event!!");
      
    	if (dev == BFM_INPUT_KEYBOARD)
    	{
    		GePrint("any key is pressed");
    		if(chn == KEY_DELETE)
    		{
    			if (!selection)
    				return true;
      
    			BaseContainer actionk(BFM_ACTION);
    			actionk.SetInt32(BFM_ACTION_ID, GetId());
    			actionk.SetInt32(BFM_ACTION_VALUE, 0);
    			actionk.SetInt32(BFM_ACTION_UPDATE, true);
    			
    			removeSelectedNodes();
    			removeSelectedWires();
    			//InvokeCommandCall(GetDialog(), COMMANDMSG_VALUECHANGED, actionk);
    			SendParentMessage(actionk);
    			return true;
    		}
    	}  
    ......
    

    the problem is:
    after a mouse click "for example selecting a node in my userarea" , this changes the data of my CustomDataType, once this is done, the focus is gone!

    so next keyboard hit is missing "the whole InputEvent() is not called at all!" , so I have to click again.
    I also tested it with your example, your example works fine!, the only difference that I see is: in many cases I may send multiple parent messages... "is this a problem?"

    though I hacked around it, not sure if this is fine or not "you may tell " , I set:
    action.SetInt32(BFM_ACTION_UPDATE, true);

    this forced it to work! , so if this is fine you can consider this solved or suggest a better alternative



  • On 30/12/2015 at 14:33, xxxxxxxx wrote:

    ok I found a pitfall!!, action.SetInt32(BFM_ACTION_UPDATE, true); actually updates immediatly BUT ignores the data change update "so the GeUserArea updates, but the internal data doesn't get a refresh "as this user area can be seen in multiple object managers, I see it only updating in 1 location when  action.SetInt32(BFM_ACTION_UPDATE, true); is active!"

    on the other hand without this line, it got the keyboard delay focus, ideas?



  • On 31/12/2015 at 04:55, xxxxxxxx wrote:

    Hi Mohamed,

    Sorry for my late reply.
    Sebastian will be back next week and I'm sure he'll be able to give you feedback and ideas for your problem.



  • On 04/01/2016 at 02:07, xxxxxxxx wrote:

    Hello Mohamed,

    your last posts are a little bit confusing. Can you post your current code of all relevant classes and functions?

    Best wishes,
    Sebastian



  • On 04/01/2016 at 04:44, xxxxxxxx wrote:

    Hi Sebastian,

    I guess the functions are getting delayed due to heavy processing "when the MatPreview is rendering the this problem happens!".

    so I guess it is a wait for event loop that get ignored due to thread being busy in rendering.
    but the problem as I posted, and the code is quite complex!! "more than 7k lines../+ I can't strip it ".



  • On 04/01/2016 at 09:10, xxxxxxxx wrote:

    Hello,

    I do not understand how material preview rendering is related to this thread. Without more specific information I don't think it is possible to give more help.

    Best wishes,
    Sebastian



  • On 05/01/2016 at 05:05, xxxxxxxx wrote:

    He Sebastian,

    it is a long story "this GeUserArea is a custom gui for a custom data type inside my MaterialData plugin".
    but I tested when rendering is off too, it didn't work for unknown reason, I guess I will accept the result anyway.

    you can consider this solved/closed.


Log in to reply