/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
//
// DragNDrop
//
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
#include "CKAll.h"
#include "CKFontManager.h"
CKObjectDeclaration *FillBehaviorDragNDropDecl();
CKERROR CreateDragNDropProto(CKBehaviorPrototype **);
int DragNDrop(const CKBehaviorContext& behcontext);
CKObjectDeclaration *FillBehaviorDragNDropDecl()
{
CKObjectDeclaration *od = CreateCKObjectDeclaration("Drag and Drop");
od->SetDescription("Enables you to drag and drop a 2D Entity.");
/* rem:
In: triggers the process.
Out: is activated when the process is completed.
Limit Rectangle: Rectangle limitting the entity. Let 0,0,0,0 if the entity
must not be constraint.
This behavior allow you to pick and move any 2D Entity, with its
hierarchy, with the possibility of constraint its moving to a given rectangle.
*/
od->SetType(CKDLL_BEHAVIORPROTOTYPE);
od->SetGuid(CKGUID(0x39c45869,0x3dcf3fc1));
od->SetAuthorGuid(VIRTOOLS_GUID);
od->SetAuthorName("Virtools");
od->SetVersion(0x00010000);
od->SetCreationFunction(CreateDragNDropProto);
od->SetCompatibleClassId(CKCID_2DENTITY);
od->SetCategory("Interface/Controls");
return od;
}
CKERROR CreateDragNDropProto(CKBehaviorPrototype **pproto)
{
CKBehaviorPrototype *proto = CreateCKBehaviorPrototype("Drag and Drop");
if(!proto) return CKERR_OUTOFMEMORY;
proto->DeclareInput("On");
proto->DeclareInput("Off");
proto->DeclareOutput("Dragged");
proto->DeclareOutput("Dropped");
proto->DeclareInParameter("Limit Rectangle",CKPGUID_RECT,"(0,0),(0,0)");
proto->DeclareLocalParameter(NULL,CKPGUID_INT,"0"); // State
proto->DeclareLocalParameter(NULL,CKPGUID_2DVECTOR,"0"); // First Mouse Position
proto->SetFlags(CK_BEHAVIORPROTOTYPE_NORMAL);
proto->SetFunction(DragNDrop);
*pproto = proto;
return CK_OK;
}
#define RELEASED 1
#define PRESSED 0
int DragNDrop(const CKBehaviorContext& behcontext)
{
CKBehavior* beh = behcontext.Behavior;
CK2dEntity* frame = (CK2dEntity*)beh->GetTarget();
if(beh->IsInputActive(0)) {
beh->ActivateInput(0, FALSE);
int state = RELEASED;
beh->SetLocalParameterValue(0,&state);
}
if(beh->IsInputActive(1)) {
beh->ActivateInput(1, FALSE);
return CKBR_OK;
}
CKInputManager* im = (CKInputManager*)behcontext.Context->GetManagerByGuid(INPUT_MANAGER_GUID);
if (!im) return CKBR_ACTIVATENEXTFRAME;
CKFontManager* fm = (CKFontManager*)behcontext.Context->GetManagerByGuid(FONT_MANAGER_GUID);
CK2dEntity* ent = fm->GetEntityUnderMouse();
VxRect lrect;
beh->GetInputParameterValue(0,&lrect);
// TODO : button configurable
int button = 0;
CKBOOL inside = FALSE;
if (ent == frame) inside = TRUE;
int state = 0;
beh->GetLocalParameterValue(0,&state);
Vx2DVector mp;
im->GetMousePosition(mp,FALSE);
if (state == PRESSED) {
Vx2DVector offset;
beh->GetLocalParameterValue(1,&offset);
offset += mp;
if (!lrect.IsNull()) lrect.Clip(offset);
frame->SetPosition(offset);
}
int oldstate = state;
if (im->IsMouseClicked(CK_MOUSEBUTTON(button)) && inside) {
Vx2DVector offset;
frame->GetPosition(offset);
offset -= mp;
beh->SetLocalParameterValue(1,&offset);
state = PRESSED;
} else {
if (im->IsMouseButtonDown(CK_MOUSEBUTTON(button))) {
} else {
if (oldstate == PRESSED) {
state = RELEASED;
} else state = RELEASED;
}
}
if (state != oldstate) { // State change
// we activate the corresponding output
beh->ActivateOutput(state);
// we store the new state
beh->SetLocalParameterValue(0,&state);
}
return CKBR_ACTIVATENEXTFRAME;
}