/*
 *******************************************************************
 * Function: CKBehavior* GetTargetCommand(const int commandId, const CKBehaviorContext& behaviorContext)
 *
 * Description : Gets target behavior object given the command ID
 *		
 * Paramters :
 *
 *   commandId			r   command id of the target object to get 
 *   behaviorContext    r   context
 *
 * Returns : 
 *              pointer to the behavior object, NULL if no object found
 *
 *******************************************************************
 */
CKBehavior* CGBLCommandController::GetTargetCommand(const int commandId, const CKBehaviorContext& behaviorContext)
{
    CKBehavior* targetBehavior = NULL;
	CKContext* context = behaviorContext.Context;

	int behaviorCount = context->GetObjectsCountByClassID(CKCID_BEHAVIOR);
	CK_ID* behaviorIds = context->GetObjectsListByClassID(CKCID_BEHAVIOR);

	int currentID;
	for (int i = 0; i < behaviorCount; ++i) 
	{
		CKBehavior* behavior = (CKBehavior*)context->GetObject(behaviorIds[i]);
		if (behavior->GetPrototypeGuid() == GUID_GBLWAITFORCOMMAND_PROTOTYPE)
		{
			CKParameterLocal *localParam = NULL;
            localParam = behavior->GetLocalParameter(2); //Get command ID
			if (localParam != NULL)
			{
				localParam->GetValue(&currentID); //Get command ID's value
				localParam = NULL;
			}
			else
			{
                break;
			}

			if (currentID == commandId)
			{
                targetBehavior = behavior;
                break;
			}
		}
	}
	return targetBehavior;
}
示例#2
0
int GetNextBBId(const CKBehaviorContext& behcontext)
{
	CKBehavior* beh = behcontext.Behavior;
	CKContext* ctx = behcontext.Context;
	
	beh->ActivateInput(0,FALSE);
	
	int count = beh->GetParent()->GetSubBehaviorLinkCount();
	int result = -1;
    
	for (int i=0; i<count; i++)
	{
		CKBehaviorLink *link =  beh->GetParent()->GetSubBehaviorLink(i);
		if (link->GetInBehaviorIO() == beh->GetOutput(0))
		{
			result   = link->GetOutBehaviorIO()->GetOwner()->GetID();
			beh->SetOutputParameterValue(0,&result);
			break;
		}
	}
	
	CKBehavior *script   = static_cast<CKBehavior*>(ctx->GetObject(result));
	if (script)
	{
		int bc = script->GetOutputCount();

		int bc2 = script->GetInputCount();

	}


	beh->ActivateOutput(0);
	beh->SetOutputParameterValue(0,&result);
	return CKBR_OK;
}
示例#3
0
/*
  *******************************************************************
  * Function: RenderCallback()
  *
  * Description : Is called from Virtools every frame. We draw the widget's visual elements in this function.
  *
  * Parameters :
  *    Passed in from Virtools. See Virtools SDK documentation:
  *    *renderContext, rw:
  *    renderObject, rw:
  *    *iArg, rw:
  *
  * Returns :  Return TRUE for success or FALSE for failure. The implications of returning FALSE are not documented in the Virtools
  * SDK documentation. Let's hope it doesn't format the user's hard disk.
  *
  *******************************************************************
*/
CKBOOL CGBLListBox::RenderCallback(CKRenderContext *renderContext, CKRenderObject* renderObject, void *iArg)
{
    const int cFixedStringBufferSize = 256;
	static VxRect fullUVRect(0.0f, 0.0f, 1.0f, 1.0f);

	CKContext* context = renderContext->GetCKContext();
	CK2dEntity* ent = CK2dEntity::Cast(renderObject);

	// Sanity check
	if (!ent) 
    {
		assert(NULL);
		return FALSE;
	}

	// Get a pointer to the building block behaviour
	CKBehavior* beh = (CKBehavior*)context->GetObject(reinterpret_cast<CK_ID>(iArg));
	if (!beh) 
		return FALSE;

	// Use clipping class to manage the clipping for us
	CGBLRenderClipper cRenderClipper(renderContext, ent);

	// Get client rectangle
	VxRect clientRect;
	ent->GetExtents(fullUVRect, clientRect);

    // Get the font from the base helper class
    VirtoolsSource::CKTextureFont* font = CGBLWidget::GetFont(context, beh);
    if (!font) 
    {
        // Don't output an error - we check for a font in the behavioural function
        return FALSE;
    }

    // Get material
    CKMaterial* material = (CKMaterial*)beh->GetInputParameterObject(eParamInputMaterial);
    if (!material) 
    {
        return FALSE;
    }

    // Are we using proportional scaling?
    CKBOOL isPropScaling = CGBLWidget::IsProportionalScaling(beh);

    // Get the font height
    float fontHeight = CGBLWidget::GetFontHeight(font, renderContext, isPropScaling);

    // Render down arrow
    CKBOOL isDownButtonPressed = FALSE;
    beh->GetLocalParameterValue(eLocalParamIsScrollDownButtonPressed, &isDownButtonPressed);

    VxRect buttonRect = GetRectDownArrow(clientRect, fontHeight);
    CGBLWidget::DrawMaterialRectangle(renderContext, material, buttonRect, 
        isDownButtonPressed ? CGBLWidgetsTheme::GetListBoxRegionDownArrowPressed() : CGBLWidgetsTheme::GetListBoxRegionDownArrowUnpressed(), 
        clientRect);
    
    // Render up arrow
    CKBOOL isUpButtonPressed = FALSE;
    beh->GetLocalParameterValue(eLocalParamIsScrollUpButtonPressed, &isUpButtonPressed);

    buttonRect = GetRectUpArrow(clientRect, fontHeight);
    CGBLWidget::DrawMaterialRectangle(renderContext, material, buttonRect, 
        isUpButtonPressed ? CGBLWidgetsTheme::GetListBoxRegionUpArrowPressed() : CGBLWidgetsTheme::GetListBoxRegionUpArrowUnpressed(), 
        clientRect);

    // Render headings if present

    // Get columns array
    CKDataArray* columnsArray = static_cast<CKDataArray*>(beh->GetInputParameterObject(eParamInputColumnsArray));
    int numColumns = columnsArray ? columnsArray->GetRowCount() : 1;

    // If we have at least one row in the columns array, we are drawing headings
    if (columnsArray && (columnsArray->GetRowCount() >= 1)) 
    {
        VxRect headingsRect = GetRectHeadings(clientRect, fontHeight, columnsArray);

        VxRect headingRect = headingsRect;
        for (int column = 0;column < numColumns;column++) 
        {
            headingRect.right = headingRect.left + GetColumnWidth(beh, columnsArray, column) * headingsRect.GetWidth() / 100.0f;

            // Draw heading background
            CGBLWidget::DrawMaterialRectangle(renderContext, material, headingRect, 
                CGBLWidgetsTheme::GetListBoxRegionHeadingBackground(), headingsRect);

            // Draw heading text
            CKCHAR fixedBuffer[cFixedStringBufferSize];
            CKSTRING headingText = NULL;
            int labelLength =  columnsArray->GetElementStringValue(column, eColumnsArrayColumnHeading, NULL);
            if (labelLength > cFixedStringBufferSize)
                headingText = new CKCHAR[labelLength];
            else
                headingText = fixedBuffer;

            if (headingText) 
            {
                columnsArray->GetElementStringValue(column, eColumnsArrayColumnHeading, headingText);
            	
                int textOptions = TEXT_CLIP;
                if (isPropScaling)
                    textOptions |= TEXT_SCREEN;

                VxRect clippedHeadingRect = headingRect;
                clippedHeadingRect.Clip(headingsRect);

                // Use margin
                clippedHeadingRect.left += CGBLWidgetsTheme::GetStringListBoxTextMargin() * fontHeight;

                font->DrawCKText(renderContext, ent, headingText, VALIGN_BOTTOM | HALIGN_LEFT, clippedHeadingRect, NULL, textOptions, TRUE);

                // Delete the buffer?
                if (headingText != fixedBuffer)
                    delete[] headingText;
            }                

            // Move to next heading
            headingRect.left = headingRect.right;
        }
    }

    // Get data array and output error if we don't have one
    CKDataArray* stringListArray = static_cast<CKDataArray*>(beh->GetInputParameterObject(eParamInputStringListArray));
    if (!stringListArray) 
        return FALSE;

    // Get space for list box strings area
    VxRect stringListRect = GetRectStringList(clientRect, fontHeight, columnsArray);

    // Draw columns backgrounds now
    VxRect columnRect = stringListRect;
    for (int column = 0;column < numColumns;column++) 
    {
        columnRect.right = columnRect.left + GetColumnWidth(beh, columnsArray, column) * stringListRect.GetWidth() / 100.0f;

        // Draw column background
        CGBLWidget::DrawMaterialRectangle(renderContext, material, columnRect, 
            CGBLWidgetsTheme::GetListBoxRegionColumnBackground(), stringListRect);

        // Move to next column
        columnRect.left = columnRect.right;
    }

    // Get the scroll offset
    int scrollOffset = 0;
    beh->GetLocalParameterValue(eLocalParamScrollOffset, &scrollOffset);

    // Range check the scroll offset
    int nRowsVisible = static_cast<int>(stringListRect.GetHeight() / fontHeight + 0.01);    // Add fudge factor to avoid rounding down errors

    if ((scrollOffset + nRowsVisible - 1) >= stringListArray->GetRowCount())
        scrollOffset = stringListArray->GetRowCount() - nRowsVisible;
    if (scrollOffset < 0)
        scrollOffset = 0;

    // Re-set scroll offset local param
    beh->SetLocalParameterValue(eLocalParamScrollOffset, &scrollOffset);

    // Draw any selection highlights
    VxRect rowRect;
    for (int row = scrollOffset; 
        CGBLWidget::GetListRowRect(stringListRect, row, scrollOffset, stringListArray->GetRowCount(), fontHeight, &rowRect); row++) 
    {
        CKBOOL rowSelected = FALSE;

        stringListArray->GetElementValue(row, CGBLWidget::eStringListArrayColumnSelected, &rowSelected);
        if (rowSelected) 
            CGBLWidget::DrawMaterialRectangle(renderContext, material, rowRect, CGBLWidgetsTheme::GetListBoxRegionSelectedBackground());
    }

    // Draw column strings now
    columnRect = stringListRect;
    for (int column = 0;column < numColumns;column++) 
    {
        columnRect.right = columnRect.left + GetColumnWidth(beh, columnsArray, column) * stringListRect.GetWidth() / 100.0f;

        // Select which column to pick from the string list array
        int arrayColumn;
        if (column) 
            arrayColumn = column + CGBLWidget::eStringListArrayColumnAdditionalLabels - 1;
        else
            arrayColumn = column;

        VxRect clippedColumnRect = columnRect;
        clippedColumnRect.Clip(stringListRect);

        CGBLWidget::DrawStringListColumn(renderContext, ent, font, isPropScaling, stringListArray, 
            arrayColumn, clippedColumnRect, scrollOffset, column == 0);

        // Move to next column
        columnRect.left = columnRect.right;
    }

    // Disable the scroll buttons?
    if (scrollOffset == 0)
        CGBLWidget::DrawDisabledRectangle(renderContext, GetRectUpArrow(clientRect, fontHeight), clientRect);

    if ((scrollOffset + nRowsVisible) > (stringListArray->GetRowCount() - 1) )
        CGBLWidget::DrawDisabledRectangle(renderContext, GetRectDownArrow(clientRect, fontHeight), clientRect);


   	CKBOOL isFocussed = CGBLWidget::IsWidgetFocussed(beh);

	// If we're focussed, draw a focus rectangle around our focussed item
	if (isFocussed) 
    {
        int focussedItem = 0;
        beh->GetLocalParameterValue(eLocalParamFocussedItem, &focussedItem);

        if (CGBLWidget::GetListRowRect(stringListRect, focussedItem, scrollOffset, stringListArray->GetRowCount(), fontHeight, &rowRect))
		{
		    // draw focus around the selected item
			CGBLWidget::DrawFocusHighlight(renderContext, beh, rowRect, FALSE);
		}
		else
		{
			// see if the list is empty
			if ((!stringListArray)||(stringListArray->GetRowCount()<=0))
			{
				// Draw focus around the full list box
				CGBLWidget::DrawFocusHighlight(renderContext, beh, clientRect, FALSE);
			}
			else
			{
				// The list isnt empty but the current item is unselectable
			}
		}
	}

    // If widget is disabled, draw whole widget area disabled
    if (!CGBLWidget::IsWidgetEnabled(beh)) 
    {
        CGBLWidget::DrawDisabledRectangle(renderContext, GetRectUpArrow(clientRect, fontHeight), clientRect);
        CGBLWidget::DrawDisabledRectangle(renderContext, GetRectDownArrow(clientRect, fontHeight), clientRect);
        CGBLWidget::DrawDisabledRectangle(renderContext, GetRectHeadings(clientRect, fontHeight, columnsArray), clientRect);
        CGBLWidget::DrawDisabledRectangle(renderContext, GetRectStringList(clientRect, fontHeight, columnsArray), clientRect);
	}

    return TRUE;
}