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