AeBinEditorEdit.c++ 8.29 KB
//
// AeBinEditorEdit.c++
//
// Routines for handling UI edit events
//


#include <assert.h>
#include <Xm/Xm.h>
#include "Matrix.h"

#include "GList.h"
#include "AeBinEditor.h"
#include "AeAssetBase.h"
#include "AeAssetBin.h"
#include "AeAssetBinUI.h"
#include "AeAssetUI.h"
#include "AeFieldUI.h"
#include "AeBinView.h"
#include "AePlayer.h"


XrmQuark AeBinEditor::qLeft = 0;
XrmQuark AeBinEditor::qRight = 0;
XrmQuark AeBinEditor::qUp = 0;
XrmQuark AeBinEditor::qDown = 0;


AeBinEditor *	AeBinEditor::fMenuEditor = NULL;
AeAssetUI *	AeBinEditor::fMenuAssetUI = NULL;
AeFieldUI *	AeBinEditor::fMenuFieldUI = NULL;



void
AeBinEditor::EnterCell (Widget list, XbaeMatrixEnterCellCallbackStruct * ecData)
{
    AeAssetUI * assetUI;
    AeFieldUI *	fieldUI;

    assetUI = (AeAssetUI *)XbaeMatrixGetRowUserData (list, ecData->row);    
    fieldUI = (AeFieldUI *)XbaeMatrixGetColumnUserData (list, ecData->column);

    if (fieldUI && assetUI)
    {
	assert (assetUI->GetRow () == ecData->row);

	ecData->doit = assetUI->IsEditable (fieldUI);
	ecData->select_text = True;		// Always select text for editing
    }
}


void
AeBinEditor::LeaveCell (Widget list, XbaeMatrixLeaveCellCallbackStruct * lcData)
{
    AeAssetUI *	assetUI;
    AeFieldUI *	fieldUI;
    Boolean	changed;

    assetUI = (AeAssetUI *)XbaeMatrixGetRowUserData (list, lcData->row);    
    fieldUI = (AeFieldUI *)XbaeMatrixGetColumnUserData (list, lcData->column);

    if (fieldUI && assetUI)
    {
	assert (assetUI->GetRow () == lcData->row);

	if (lcData->doit = assetUI->VerifyAndSetFieldString (fieldUI, lcData->value, &changed))
	{
	    if (changed)
		fAssetBase->NotifyUpdate (assetUI->GetAsset ());
	}
    }
}


void
AeBinEditor::ModifyVerify (Widget list, XbaeMatrixModifyVerifyCallbackStruct * mvData)
{
    AeFieldUI *	fieldUI;

    fieldUI = (AeFieldUI *)XbaeMatrixGetColumnUserData (list, mvData->column);

    if (fieldUI)
	mvData->verify->doit = fieldUI->VerifyInput (mvData->verify, mvData->prev_text);
}


void
AeBinEditor::DrawCell (Widget list, XbaeMatrixDrawCellCallbackStruct * dcData)
{
    AeAssetUI *	assetUI;
    AeFieldUI * fieldUI;

    assetUI = (AeAssetUI *)XbaeMatrixGetRowUserData (list, dcData->row);
    fieldUI = (AeFieldUI *)XbaeMatrixGetColumnUserData (list, dcData->column);

    if (fieldUI && assetUI)
    {
	assert (assetUI->GetRow () == dcData->row);

	if (assetUI->GetAsset()->IsSelected())
	{
	    dcData->foreground = fView->ListGetSelectForeground ();
	    dcData->background = fView->ListGetSelectBackground ();
	}

	if (fieldUI->IsIcon ())
	{
	    dcData->type = XbaePixmap;
	    dcData->pixmap = assetUI->GetIcon ();
	    if ((assetUI->GetAsset())->IsOnline ())
		dcData->foreground = fView->ListGetOnlineColor ();
	}
	else
	{
	    dcData->type = XbaeString;
	    assetUI->GetFieldString (fieldUI, dcData->string);
	}
    }
}


void
AeBinEditor::SelectCell (Widget list, XbaeMatrixSelectCellCallbackStruct * scData)
{
    AeAssetUI *	assetUI;
    AeFieldUI *	fieldUI;
    TEditModifier modifier;

    assetUI = (AeAssetUI *)XbaeMatrixGetRowUserData (list, scData->row);
    fieldUI = (AeFieldUI *)XbaeMatrixGetColumnUserData (list, scData->column);

    if (fieldUI && assetUI)
    {
	assert (assetUI->GetRow () == scData->row);

	modifier = params2modifier (scData->num_params, scData->params);

	// if the alt key was clicked, then text edit the value
	if (modifier == kModAlt && assetUI->IsEditable (fieldUI))
	    XbaeMatrixEditCell (list, scData->row, scData->column);
	    
	// else let the field handle it specially
	else
	{
	    if (!fieldUI->HandleButtonPress (this, assetUI, scData->event, modifier))
		if (assetUI->IsEditable (fieldUI))
		    XbaeMatrixEditCell (list, scData->row, scData->column);
	}
		
    }
}


void
AeBinEditor::TraverseCell (Widget list, XbaeMatrixTraverseCellCallbackStruct * tcData)
{
    AeAssetUI *	assetUI;
    AeFieldUI * fieldUI;

    tcData->next_row = tcData->row;
    tcData->next_column = tcData->column;

    do
    {
	if (tcData->qparam == qDown)
	{
	    if (++tcData->next_row >= tcData->num_rows)
		tcData->next_row = 0;
	}
	
	else if (tcData->qparam == qUp)
	{
	    if (--tcData->next_row < 0)
		tcData->next_row = tcData->num_rows - 1;
	}
		
	else if (tcData->qparam == qLeft)
	{
	    if (--tcData->next_column < 0)
		tcData->next_column = tcData->num_columns - 1;
	}

	else if (tcData->qparam == qRight)
	{
	    if (++tcData->next_column >= tcData->num_columns)
		tcData->next_column = 0;
	}
	
	else
	    return;

	assetUI = (AeAssetUI *)XbaeMatrixGetRowUserData (list, tcData->next_row);
	fieldUI = (AeFieldUI *)XbaeMatrixGetColumnUserData (list, tcData->next_column);

    } while (!assetUI->IsEditable (fieldUI));

}


void
AeBinEditor::DefaultAction (Widget list, XbaeMatrixDefaultActionCallbackStruct * daData)
{
    AeAssetUI *	assetUI;
    AeFieldUI * fieldUI;

    assetUI = (AeAssetUI *)XbaeMatrixGetRowUserData (list, daData->row);
    fieldUI = (AeFieldUI *)XbaeMatrixGetColumnUserData (list, daData->column);

    if (fieldUI && assetUI)
	fieldUI->HandleDoubleClick (this, assetUI, daData->event, kModNone);
}


void
AeBinEditor::MenuCallback (Widget list, XtPointer value, XtPointer callData)
{
    assert (AeBinEditor::fMenuEditor);
    assert (AeBinEditor::fMenuFieldUI);
    assert (AeBinEditor::fMenuAssetUI);

    AeBinEditor::fMenuEditor->SetAssetFieldValue (AeBinEditor::fMenuAssetUI,
						  AeBinEditor::fMenuFieldUI,
						  value);
}


void
AeBinEditor::SetAssetFieldValue (AeAssetUI * assetUI, AeFieldUI * fieldUI, XtPointer value)
{
    if (fieldUI->SetValue (assetUI->GetAsset (), value))
	fAssetBase->NotifyUpdate (assetUI->GetAsset ());
}


void
AeBinEditor::SelectAssetUI (AeAssetUI * assetUI, TEditModifier modifier)
{
    assert (assetUI);
    assert (fAssetBase);
    assert (fSelectionList);
    
    static AeAssetUI *	lastAssetUI = NULL;
    static AeAssetUI *	pivotAssetUI = NULL;

    if (modifier == kModMotion && lastAssetUI == assetUI)
	return;

    // if we're dragging out a selection, then select or
    // deselect all the assets in between the current assetUI
    // and the last assetUI
    if (modifier == kModMotion)
    {
	AeAssetUI *	aUI;
	int		startRow, endRow, nRows, i;
	int		lastRow = lastAssetUI->GetRow ();
	int		curRow = assetUI->GetRow ();
	int		pivotRow = pivotAssetUI->GetRow ();
	
	assert (lastAssetUI);
	assert (pivotAssetUI);


	// select or deselect items from the pivot point
	// and downwards (larger row numbers)
	if (lastRow > pivotRow || curRow > pivotRow)
	{
	    if (lastRow < curRow)
	    {
		startRow = lastRow;
		endRow = curRow;
	    }
	    else
	    {
		startRow = curRow;
		endRow = lastRow;
	    }

	    // clip startRow to the pivotRow
	    if (startRow < pivotRow)
		startRow = pivotRow;

	    nRows = endRow - startRow;

	    for (i=startRow+1; --nRows>=0; i++)
	    {
		aUI = (AeAssetUI *)XbaeMatrixGetRowUserData (fView->ListGetWidget (), i);
		aUI->GetAsset()->ToggleSelect ();
		fAssetBase->NotifySelect (aUI->GetAsset ());
	    }
	}

	// select or deselect items from the pivot point
	// and upwards (smaller row numbers)
	if (lastRow < pivotRow || curRow < pivotRow)
	{
	    if (lastRow > curRow)
	    {
		startRow = lastRow;
		endRow = curRow;
	    }
	    else
	    {
		startRow = curRow;
		endRow = lastRow;
	    }

	    // clip startRow to the pivotRow
	    if (startRow > pivotRow)
		startRow = pivotRow;

	    nRows = startRow - endRow;

	    for (i=startRow-1; --nRows>=0; i--)
	    {
		aUI = (AeAssetUI *)XbaeMatrixGetRowUserData (fView->ListGetWidget (), i);
		aUI->GetAsset()->ToggleSelect ();
		fAssetBase->NotifySelect (aUI->GetAsset ());
	    }
	}
    }
    else if (modifier == kModDown || modifier == kModShift)
    {
	Boolean selected = assetUI->GetAsset()->IsSelected ();

	// if selection was exclusive clear all other selections
	if (modifier == kModDown)
	    DeselectAllAssets ();

	// select if it wasn't originally selected
	if (!selected)
	{
	    assetUI->GetAsset()->SetSelect (True);
	    fAssetBase->NotifySelect (assetUI->GetAsset ());
	}

	pivotAssetUI = assetUI;
    }

    lastAssetUI = assetUI;
}


TEditModifier
AeBinEditor::params2modifier (int nParams, String * params)
{
    if (nParams)
    {
	if (!strcmp (*params, "Shift"))
	    return kModShift;

	if (!strcmp (*params, "Alt"))
	    return kModAlt;

	if (!strcmp (*params, "Down"))
	    return kModDown;

	if (!strcmp (*params, "Motion"))
	    return kModMotion;

	if (!strcmp (*params, "Up"))
	    return kModUp;
    }

    return kModNone;
}