///////////////////////////////////////////////////// ///////////////////////////////////////////////////// // // Slider // ///////////////////////////////////////////////////// ///////////////////////////////////////////////////// #include "CKAll.h" #include "CKFontManager.h" CKObjectDeclaration *FillBehaviorSliderDecl(); CKERROR CreateSliderProto(CKBehaviorPrototype **); int Slider(const CKBehaviorContext& behcontext); CKERROR SliderCallback(const CKBehaviorContext& behcontext); CKBOOL SliderRenderCallback(CKRenderContext *context,CKRenderObject* ent,void *Argument); CKObjectDeclaration *FillBehaviorSliderDecl() { CKObjectDeclaration *od = CreateCKObjectDeclaration("Slider"); od->SetDescription(""); /* rem: In: triggers the process.
Out: is activated when the process is completed.

Material: .
*/ od->SetType(CKDLL_BEHAVIORPROTOTYPE); od->SetGuid(CKGUID(0x571379bf,0xe8233bd)); od->SetAuthorGuid(VIRTOOLS_GUID); od->SetAuthorName("Virtools"); od->SetVersion(0x00010000); od->SetCreationFunction(CreateSliderProto); od->SetCompatibleClassId(CKCID_2DENTITY); od->SetCategory("Interface/Controls"); return od; } CKERROR CreateSliderProto(CKBehaviorPrototype **pproto) { CKBehaviorPrototype *proto = CreateCKBehaviorPrototype("Slider"); if(!proto) return CKERR_OUTOFMEMORY; proto->DeclareInput("On"); proto->DeclareInput("Off"); proto->DeclareOutput("Exit On"); proto->DeclareOutput("Exit Off"); proto->DeclareOutput("Value Changed"); proto->DeclareInParameter("Steps", CKPGUID_INT,"10"); proto->DeclareInParameter("Initial Value", CKPGUID_INT,"0"); proto->DeclareInParameter("Slider", CKPGUID_2DENTITY); proto->DeclareInParameter("Relative", CKPGUID_BOOL,"FALSE"); proto->DeclareInParameter("Plus Arrow", CKPGUID_2DENTITY); proto->DeclareInParameter("Minus Arrow", CKPGUID_2DENTITY); proto->DeclareInParameter("Slider Background", CKPGUID_MATERIAL); proto->DeclareLocalParameter(NULL,CKPGUID_INT,"0"); // State proto->DeclareSetting("Vertical",CKPGUID_BOOL,"FALSE"); proto->DeclareOutParameter("Value",CKPGUID_INT,"0"); proto->DeclareOutParameter("Percentage",CKPGUID_PERCENTAGE,"0"); proto->SetFlags(CK_BEHAVIORPROTOTYPE_NORMAL); proto->SetFunction(Slider); *pproto = proto; return CK_OK; } #define RELEASED 0 #define PRESSED 1 #define ROLLOVER 2 void MoveSlider(int value,int steps,CK2dEntity* slider, VxRect& framerect,CKBOOL scale,CKBOOL vert) { VxRect sliderrect; slider->GetRect(sliderrect); if (vert) { // Vertical slider // Horizontal placement (center for now) sliderrect.VMove(framerect.left+framerect.GetWidth()*0.5f-sliderrect.GetWidth()*0.5f); float f = (float)value/steps; if (f > 1.0f) f = 1.0f; else if (f < 0.0f) f = 0.0f; if (scale) { sliderrect.top = framerect.top; sliderrect.bottom = framerect.top+f*framerect.GetHeight(); } else { sliderrect.VMove(framerect.top+f*(framerect.GetHeight() - sliderrect.GetHeight())); } } else { // Horizontal slider // Vertical placement (center for now) sliderrect.VMove(framerect.top+framerect.GetHeight()*0.5f-sliderrect.GetHeight()*0.5f); float f = (float)value/steps; if (f > 1.0f) f = 1.0f; else if (f < 0.0f) f = 0.0f; if (scale) { sliderrect.left = framerect.left; sliderrect.right = framerect.left+f*framerect.GetWidth(); } else { sliderrect.HMove(framerect.left+f*(framerect.GetWidth() - sliderrect.GetWidth())); } } slider->SetRect(sliderrect); } int Slider(const CKBehaviorContext& behcontext) { CKBehavior* beh = behcontext.Behavior; if(beh->IsInputActive(1)) { beh->ActivateInput(1, FALSE); return CKBR_OK; } CK2dEntity* frame = (CK2dEntity*)beh->GetTarget(); if (!frame) return CKBR_ACTIVATENEXTFRAME; VxRect framerect; frame->GetRect(framerect); CK2dEntity* slider = (CK2dEntity*)beh->GetInputParameterObject(2); if (!slider) return CKBR_ACTIVATENEXTFRAME; int* oldvalue = (int*)beh->GetOutputParameterWriteDataPtr(0); int steps = 10; beh->GetInputParameterValue(0,&steps); CKBOOL scale = FALSE; beh->GetInputParameterValue(3,&scale); CKBOOL vert = FALSE; beh->GetLocalParameterValue(1,&vert); if(beh->IsInputActive(0)) { beh->ActivateInput(0, FALSE); int state = 0; beh->SetLocalParameterValue(0,&state); int initialvalue = 0; beh->GetInputParameterValue(1,&initialvalue); MoveSlider(initialvalue,steps,slider,framerect,scale,vert); } CKInputManager* im = (CKInputManager*)behcontext.Context->GetManagerByGuid(INPUT_MANAGER_GUID); if (!im) return CKBR_ACTIVATENEXTFRAME; // TODO : button configurable int button = 0; VxRect rect; slider->GetRect(rect); Vx2DVector mp; im->GetMousePosition(mp,FALSE); CKBOOL inside = FALSE; if (rect.IsInside(mp)) inside = TRUE; int state = 0; beh->GetLocalParameterValue(0,&state); int oldstate = state; if (state & PRESSED) { // we calculate the new value, according to the mouse position int value = (int)((steps+1)*(mp.x - framerect.left)/framerect.GetWidth()); if (value != *oldvalue) { *oldvalue = value; MoveSlider(value,steps,slider,framerect,scale,vert); } } if (im->IsMouseClicked(CK_MOUSEBUTTON(button)) && inside) { state = PRESSED; } else { if (im->IsMouseButtonDown(CK_MOUSEBUTTON(button))) { if (framerect.IsInside(mp)) { // we clicked on the slider background : direct jump // we calculate the new value, according to the mouse position int value = (int)((steps+1)*(mp.x - framerect.left)/framerect.GetWidth()); if (value != *oldvalue) { *oldvalue = value; MoveSlider(value,steps,slider,framerect,scale,vert); } } } else { if (state & PRESSED) { state = RELEASED; } else if (inside) state = ROLLOVER; 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); } // add pre render callback frame->AddPreRenderCallBack(SliderRenderCallback,(void*)beh->GetID(),TRUE); return CKBR_ACTIVATENEXTFRAME; } CKBOOL SliderRenderCallback(CKRenderContext *dev,CKRenderObject* ent,void* iArg) { static VxRect fulluv(0,0,1.0f,1.0f); CKContext* ctx = dev->GetCKContext(); CKBehavior* beh = (CKBehavior*)ctx->GetObject((CK_ID)iArg); if (!beh) return TRUE; CKFontManager* fm = (CKFontManager*)ctx->GetManagerByGuid(FONT_MANAGER_GUID); CK2dEntity* frame = (CK2dEntity*)beh->GetTarget(); if (!frame) return TRUE; // 2D Frame Zone VxRect rect; frame->GetRect(rect); int state = 0; beh->GetLocalParameterValue(0,&state); CKMaterial* mat = (CKMaterial*)beh->GetInputParameterObject(6); VxColor col(1.0f,1.0f,1.0f,1.0f);if (mat) col = mat->GetDiffuse(); // We draw the button background DrawFillRectangle(dev,col.GetRGBA(),mat,rect,fulluv); return TRUE; }