Calling every menu of a GVNode



  • On 27/06/2017 at 14:54, xxxxxxxx wrote:

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

    ---------
    I'm trying to make some usability tools for XPresso, but I'm not finding certain items from the documentation.

    What I want to do is open several GvNode popup menus via code, without the user having to do mouse operations in the XPresso Editor window.

    So far the only item I've found was the NodeContextMenu() from NodeGUI, which isn't what I'm looking for. Is it possible to invoke/read the FillPortMenu() and FillPortsMenu() method in a GvNode somehow?



  • On 28/06/2017 at 05:54, xxxxxxxx wrote:

    Hi,

    actually I'm not quite sure, I understand the question or intention. Is it about getting access to the data? Presenting a menu to the user? Or executing menu items?

    Anyway, it is possible to call FillPortMenu() and FillPortsMenu().
    You just need to get the GvOperatorData from the GvNode via GetOperatorData().
    Just don't expect too much from FillPortMenu() as a node will only fill menu entries additional to the standard four. None of the built-in nodes does this.

    Furthermore GvPortDescription might also be helpful in this context, get it via GetPortDescription() from the node.

    Not sure this helps...



  • On 28/06/2017 at 07:35, xxxxxxxx wrote:

    Both actually. I want to present the "Add In/Out Port" menus and after that, execute them.
    GetOperatorData seems to do the trick. Here's a snippet I'm using in my GeUserArea's InputEvent method.

      
    // "node" is a GvNode processed earlier  
      
    BaseContainer   names, ids, popupbc;  
    GeData          gedata;  
    GvOperatorData* gvopdata = node->GetOperatorData();  
      
    // get inports from node  
    Int32           ct       = gvopdata->FillPortsMenu( node, names, ids, ID_GV_VALUE_TYPE_NONE, GV_PORT_INPUT, GV_MESSAGE_FIRST_DATA_ID );  
      
    // iterate from FillPortsMenu, then add popup menu entries.  
    Int32 i = 0, bcindex;  
    while ( true )  
    {  
      bcindex = names.GetIndexId( i++ );  
      if ( bcindex == NOTOK )  
      {  
      break;  
      }    
      popupbc.SetString( ids.GetInt32( bcindex ), names.GetString( bcindex ) );  
    }  
    Int32 screenx = msg.GetInt32( BFM_INPUT_X ),  
        screeny = msg.GetInt32( BFM_INPUT_Y );  
    Local2Screen( &screenx, &screeny );  
    Int32 menuselect = ShowPopupMenu( nullptr, screenx, screeny, popupbc, POPUP_RIGHT );  
      
    // process selected menu entry  
    

    One problem right now is my code doesn't iterate through sub-containers yet (e.g. Coordinatess, Object Properties in an Object OperatorNode.) I'll try and figure it out later, then I'll post an update.

    Thanks!



  • On 28/06/2017 at 14:25, xxxxxxxx wrote:

    Okay, I just overcomplicated my code for no reason. I just needed to directly use the returned names BaseContainer into ShowPopupMenu()

      
    // "node" is a GvNode processed earlier whose menus will be displayed  
      
    // get inports from node  
    BaseContainer   names, ids;  
    GvOperatorData* gvopdata = node->GetOperatorData();  
    Int32           ct       = gvopdata->FillPortsMenu( node, names, ids, ID_GV_VALUE_TYPE_NONE, GV_PORT_INPUT, GV_MESSAGE_FIRST_DATA_ID );  
      
    // display popup below mouse cursor  
    Int32 screenx = msg.GetInt32( BFM_INPUT_X ),  
        screeny = msg.GetInt32( BFM_INPUT_Y );  
    Local2Screen( &screenx, &screeny );  
    Int32 menuselect = ShowPopupMenu( nullptr, screenx, screeny, names, POPUP_RIGHT );  
      
    // process node with returned value from "menuselect", use "ids" as id lookup table  
    if ( node->AddPortIsOK( GV_PORT_INPUT, ids.GetInt32( menuselect ) ) )  
    {  
      node->AddPort( GV_PORT_INPUT, ids.GetInt32( menuselect ) );  
    }  
    

Log in to reply