Drag and Drop action inside dialog



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



  • 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;  
    }
    


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



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



  • 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://plugincafe.maxon.net/topic/6844/7627_how-to-use-handlemousedrag
     
    Kind regards,
     
    WP.


Log in to reply