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