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
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Drag and Drop action inside dialog

    SDK Help
    0
    5
    443
    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
      Helper
      last edited by

      On 20/01/2013 at 22:30, xxxxxxxx wrote:

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

      ---------
      Hi Folks,
       
      I've got myself a custom dialog with two groups side by side in it. The first one has a html browser in it. The second group has a GeUserArea I'm working on. I'm using the browser to search for images on my hard drive. All is working fine up to this point.
       
      What I wish to do now is have the userarea update while the mouse button is still held down during a drag operation. I can get messages to work once I let go of the mouse button etc, but I can't get things to happen in the user area while the drag is still in process. It's important that it happens here. How does one go about doing this?
       
      I've done a fair bit of experiment with this - DRAG_flags and FOCUS_ change flags in the DLG and UA Message() etc - but I just can't seem to get the user area to update while the drag is still in process. Is anyone able to explain the process of what might need to happen here in order for this to work?
       
      Regards,
       
      WP.

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

        On 21/01/2013 at 06:53, xxxxxxxx wrote:

        This is way too much code and is not relevant to a drag-and-drop operation, but it may provide some way to check the mouse location while dragging in the GeUserArea (as long as these event messages are not being overridden or ignored during the drag-and-drop process!).  The areas of importance are 'while (GetInputState(...)).  Hope it helps!

        / GeUserArea.InputEvent()  
        //*---------------------------------------------------------------------------*  
        Bool iSUserArea::InputEvent(const BaseContainer &msg)  
        //*---------------------------------------------------------------------------*  
        {  
          // Mouse Events  
          if (msg.GetLong(BFM_INPUT_DEVICE) == BFM_INPUT_MOUSE) return HandleMouseEvents(msg);  
          return FALSE;  
        }  
        // iSUserArea.HandleMouse  
        //*---------------------------------------------------------------------------*  
        Bool iSUserArea::HandleMouseEvents(const BaseContainer& msg)  
        //*---------------------------------------------------------------------------*  
        {  
          // Get Mouse Click location and other information  
          LONG    chn =                        msg.GetLong(BFM_INPUT_CHANNEL);  
          // Left Button  
          if (chn == BFM_INPUT_MOUSELEFT)        return HandleMouse_LeftButton(msg);  
          return TRUE;  
        }  
        //*---------------------------------------------------------------------------*  
        Bool iSUserArea::HandleMouse_LeftButton(const BaseContainer& msg)  
        //*---------------------------------------------------------------------------*  
        {  
          // Get Mouse Click location and other information  
          LONG            mx =        msg.GetLong(BFM_INPUT_X);  
          LONG            my =        msg.GetLong(BFM_INPUT_Y);  
          Global2Local(&mx,&my);  
          LONG            pX, pY;  
          ShaderNode*        snode =        IsOverNode(&pX, &pY, mx, my);  
          // Do Something with ShaderNode  
          if (snode)                    return HandleMouse_LBNode(snode, msg, pX, pY, mx, my);  
          // Over Background Area  
          // - Click - Remove all current selections  
          // - Drag - Create/Add to/Remove from Selection  
          return HandleMouse_LBBackground(msg, mx, my);  
        }  
        //*---------------------------------------------------------------------------*  
        Bool iSUserArea::HandleMouse_LBNode(ShaderNode* snode, const BaseContainer& msg, LONG pX, LONG pY, LONG mx, LONG my)  
        //*---------------------------------------------------------------------------*  
        {  
          // Get Mouse Click location and other information  
          Bool            dblclk =    msg.GetBool(BFM_INPUT_DOUBLECLICK);  
          LONG            qua =        msg.GetLong(BFM_INPUT_QUALIFIER);  
          
          // Setup for dragging  
          BaseContainer    action(BFM_ACTION);  
          BaseContainer    state;  
          action.SetLong(BFM_ACTION_ID,GetId());  
          action.SetLong(BFM_ACTION_VALUE,0L);  
          
          // General variables  
          LONG            i, scount;  
          ShaderNode*        dnode =        NULL;  
          NodeInput*        dinput =    NULL;  
          
          LONG        width =            GetWidth();  
          LONG        height =        GetHeight();  
          LONG        hw =            width>>1;  
          LONG        hh =            height>>1;  
          // Is mouse over ShaderNode Header?  
          if (my < (pY+cellHeight))  
          {  
              // Is mouse over Show/Hide Button  
              if (mx > (pX+previewOffset))  
              {  
                  snode->InvertShowPreview();  
              }  
              // Is mouse over Expand/Collapse Button  
              else if ((mx > (pX+expandOffset)) && (mx < (pX+expandOffset+jackplugSize)))  
              {  
                  snode->InvertExpanded();  
              }  
              // Is mouse over Output  
              else if (mx < (pX+2L+jackplugSize))  
              {  
                  // Get starting values  
                  if (snode->IsInstanceOf(SHADERNODETYPE_CHANNEL)) return TRUE;                  
                  startX = mx;  
                  startY = my;  
          
                  // Connecting  
                  validConnection = FALSE;  
                  drawMode = ISUA_DRAWMODE_CONNECTING;  
                  snode->SetConnecting(TRUE);  
                  while (GetInputState(BFM_INPUT_MOUSE,BFM_INPUT_MOUSELEFT,state))  
                  {  
                      if (state.GetLong(BFM_INPUT_VALUE) == 0L) break;  
          
                      endX = state.GetLong(BFM_INPUT_X);  
                      endY = state.GetLong(BFM_INPUT_Y);  
                      Global2Local(&endX,&endY);  
                      mx = endX/2L;  
                      my = endY/2L;  
          
                      // Check for UserArea boundary, scroll if necessary  
                      if (endX <= 0L)  
                      {  
                          windowX += mx;  
                          startX -= mx;  
                      }  
                      else if (endX >= width)  
                      {  
                          windowX += (mx-hw);  
                          startX -= (mx-hw);  
                      }  
                      if (endY <= 0L)  
                      {  
                          windowY += my;  
                          startY -= my;  
                      }  
                      else if (endY >= height)  
                      {  
                          windowY += (my-hh);  
                          startY -= (my-hh);  
                      }  
          
                      // Check for Destination input  
                      validConnection = FALSE;  
                      for (dnode = ishader->GetLastSNode(); dnode; dnode = (ShaderNode* )dnode->GetPrev())  
                      {  
                          if ((dnode == snode) || !dnode->GetExpanded()) continue;  
                          // Is it even near the node in question  
                          dnode->GetPos(&pX, &pY);  
                          pX -= windowX;  
                          pY -= windowY;  
                          if ((endX >= pX) && (endY >= pY) && (endX < (pX+cellWidth)) && (endY < (pY+snodeBoxHeight[dnode->GetType()])))  
                              if (validConnection = (dinput = IsOverNodeInput(dnode, pX, pY, endX, endY))?TRUE:FALSE) break;  
                      }  
          
                      Redraw();  
                      action.SetLong(BFM_ACTION_INDRAG,TRUE);  
                      SendParentMessage(action);  
                  }  
                  drawMode = ISUA_DRAWMODE_NORMAL;  
                  snode->SetConnecting(FALSE);  
          
                  if (dnode && validConnection)  
                  {  
                      // Check for circular connections  
                      scount = snode->GetNodeCount();  
                      for (i = 0L; i != scount; ++i)  
                      {  
                          if (snode->GetNodeInput(i)->GetNode() == dnode) return ErrorException::Throw(GeLoadString(ISHERR_CIRCULARNODE));  
                      }  
                      // Break existing connection  
                      if (dnode = dinput->GetNode()) dnode->DecConnect();  
                      // Make the connection!  
                      dinput->SetNode(snode);  
                      snode->IncConnect();  
                      ishader->UpdatePreview(FALSE);  
                  }  
              }  
              // Edit Node data  
              else if (dblclk)  
              {  
                  ishader->SetEditSNode(snode);  
                  ishader->SelectAll(FALSE);  
                  ishader->BringToFront(snode);  
              }  
              // Drag ShaderNodes  
              else  
              {  
                  ishader->BringToFront(snode);  
                  Redraw();  
          
                  while (GetInputState(BFM_INPUT_MOUSE,BFM_INPUT_MOUSELEFT,state))  
                  {  
                      if (state.GetLong(BFM_INPUT_VALUE) == 0L) break;  
          
                      SetMousePointer(MOUSE_MOVE_HAND);  
                      pX = state.GetLong(BFM_INPUT_X);  
                      pY = state.GetLong(BFM_INPUT_Y);  
                      Global2Local(&pX,&pY);  
          
                      mx = pX-mx;  
                      my = pY-my;  
                      for (snode = ishader->GetFirstSNode(); snode; snode = (ShaderNode* )snode->GetNext())  
                      {  
                          if (!snode->GetSelected()) continue;  
                          snode->Move(mx, my);  
                      }  
                      mx = pX;  
                      my = pY;  
                      Redraw();  
                      action.SetLong(BFM_ACTION_INDRAG,TRUE);  
                      SendParentMessage(action);  
                  }  
              }  
          }  
          // Edit Node data  
          else if (dblclk)        ishader->SetEditSNode(snode);  
          // Add to selection  
          else if (qua == QSHIFT) ishader->BringToFront(snode);  
          // Remove from selection  
          else if (qua == QCTRL)    ishader->SelectNode(snode, FALSE);  
          // Remove all curent selections, select this one  
          else  
          {  
              ishader->SelectAll(FALSE);  
              Redraw();  
              ishader->BringToFront(snode);  
          }  
          
          // Update and Notify  
          Redraw();  
          action.SetLong(BFM_ACTION_INDRAG,FALSE);  
          SendParentMessage(action);  
          return TRUE;  
        }  
        //*---------------------------------------------------------------------------*  
        Bool iSUserArea::HandleMouse_LBBackground(const BaseContainer& msg, LONG mx, LONG my)  
        //*---------------------------------------------------------------------------*  
        {  
          // Do nothing on DoubleClick  
          if (msg.GetBool(BFM_INPUT_DOUBLECLICK))  
          {  
              ishader->SetEditSNode(NULL);  
              return TRUE;  
          }  
          
          // Check for Keyboard Qualifiers  
          Bool            selmode;  
          LONG            qua =        msg.GetLong(BFM_INPUT_QUALIFIER);  
          if (qua == QSHIFT)            selmode = TRUE;  
          else if (qua == QCTRL)        selmode = FALSE;  
          else  
          {  
              ishader->SelectAll(FALSE);  
              selmode = TRUE;  
          }  
          
          // Setup for dragging  
          BaseContainer    action(BFM_ACTION);  
          BaseContainer    state;  
          action.SetLong(BFM_ACTION_ID,GetId());  
          action.SetLong(BFM_ACTION_VALUE,0L);  
          
          // General variables  
          LONG            width =        GetWidth();  
          LONG            height =    GetHeight();  
          LONG            hw =        width>>1;  
          LONG            hh =        height>>1;  
          LONG            rectX1 =    mx;  
          LONG            rectY1 =    my;  
          LONG            rectX2, rectY2;  
          // Drag Selecting  
          startX = rectX1;  
          startY = rectY1;  
          drawMode = ISUA_DRAWMODE_SELECTING;  
          while (GetInputState(BFM_INPUT_MOUSE,BFM_INPUT_MOUSELEFT,state))  
          {  
              if (state.GetLong(BFM_INPUT_VALUE) == 0) break;  
          
              endX = state.GetLong(BFM_INPUT_X);  
              endY = state.GetLong(BFM_INPUT_Y);  
              Global2Local(&endX,&endY);  
              mx = endX/2L;  
              my = endY/2L;  
          
              // Check for UserArea boundary, scroll if necessary  
              if (endX <= 0L)  
              {  
                  windowX += mx;  
                  startX -= mx;  
              }  
              else if (endX >= width)  
              {  
                  windowX += (mx-hw);  
                  startX -= (mx-hw);  
              }  
              if (endY <= 0L)  
              {  
                  windowY += my;  
                  startY -= my;  
              }  
              else if (endY >= height)  
              {  
                  windowY += (my-hh);  
                  startY -= (my-hh);  
              }  
          
              Redraw();  
              action.SetLong(BFM_ACTION_INDRAG,TRUE);  
              SendParentMessage(action);  
          }  
          drawMode = ISUA_DRAWMODE_NORMAL;  
          rectX2 = endX;  
          rectY2 = endY;  
          
          // Swap so that 1 is always UL, 2 LR  
          if (rectX1 > rectX2)  
          {  
              mx = rectX1;  
              rectX1 = rectX2;  
              rectX2 = mx;  
          }  
          if (rectY1 > rectY2)  
          {  
              my = rectY1;  
              rectY1 = rectY2;  
              rectY2 = my;  
          }  
          
          // Find and Select/Deselect all ShaderNodes overlapped by Rectangle  
          LONG            pX, pY;  
          for (ShaderNode* snode = ishader->GetFirstSNode(); snode; snode = (ShaderNode* )snode->GetNext())  
          {  
              snode->GetPos(&pX, &pY);  
              pX -= windowX;  
              mx = pX+cellWidth;  
              pY -= windowY;  
              my = pY+GetSNodeHeight(snode->GetType(), snode->GetExpanded(), snode->GetShowPreview());  
          
              if ((my < rectY1) || (pY > rectY2) || (mx < rectX1) || (pX > rectX2)) continue;  
              ishader->SelectNode(snode, selmode);  
          }  
          
          // Update and Notify  
          Redraw();  
          action.SetLong(BFM_ACTION_INDRAG,FALSE);  
          SendParentMessage(action);  
          return TRUE;  
        }
        
        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 21/01/2013 at 14:35, xxxxxxxx wrote:

          Hi Rob,
           
          thankyou very much for your efforts there. I certianly wasn't expecting that. I"ll need to spend some time digesting this one 😃
           
          Much appreciated,
           
          WP.

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

            On 31/01/2013 at 21:07, xxxxxxxx wrote:

            OK, I still can't seem to get this one right.
             
            I'm dragging from an html browser in my dialog, and am wanting the UA to update while the drag is in progress (if the mouse is hovering over the UA - both items are in the same dialog). I seem to be able to get a few flags to call etc once I let go of the mouse button, but can't seem to get anything to respond while the drag is in progress.
             
            Is their a core message or something of the like I might be missing?
             
            WP.

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

              On 14/02/2013 at 21:57, xxxxxxxx wrote:

              Hi Coders,
               
              just posting an update to this one. I seem to have solved this by chaning the HTML viewer to a userarea, and making my own browser (bit of a shame to have to do that but anyway). The following link may provide so further info for those seeking a solution.
              https://developers.maxon.net/forum/topic/6844/7627_how-to-use-handlemousedrag
               
              Kind regards,
               
              WP.

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