AeBinEditorNotify.c++ 5.01 KB
//
// AeBinEditorNotify.c++
//
// Contains notification routines that are called by the
// asset data base when something important happens to
// an asset (eg. created, modified, selected, etc).
//


#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"


//
// Called by asset base's client dispatch routine to
// notify clients of a new asset.
//
void
AeBinEditor::CreateAsset (AeAsset * asset, Boolean suspended)
{
    assert (asset);

    if (createAssetUI (asset))
    {
	AeAssetBinUI *	binUI;

	// when adding a new asset, we must recalc all field widths
	if (FindTypedBinUI (asset->GetType (), binUI))
	    binUI->SetNeedsWidthRecalc (True);
	
	if (!suspended)
	    fView->ListUpdateUI ();
    }	
}


//
// Called by asset base's client dispatch routine to
// notify clients of a modified asset.
//
void
AeBinEditor::UpdateAsset (AeAsset * asset, Boolean suspended)
{
    AeAsset *			parent;
    GList<AeAsset *> *		parentList;
    int				i;

    assert (asset);

    // update the asset
    updateAsset (asset);

    // update any references to the asset
    parentList = asset->GetParentList ();
    parentList->Start (i);
    while (parentList->Next (i, parent))
    {
	if (asset->IsParent (parent))
	    updateAsset (parent);
    }

    // make sure the column widths are up-to-date
    updateWidths ();		
}


//
// Called by asset base's client dispatch routine to
// notify clients of a deleted asset.
//
void
AeBinEditor::DeleteAsset (AeAsset * asset, Boolean suspended)
{
    AeAssetUI * assetUI;

    assert (asset);

    if (asset->GetClientData (this, (void **)&assetUI))
    {
	AeAssetBinUI *	binUI;

	// when deleting an asset, we must recalc all field widths
	if (FindTypedBinUI (asset->GetType (), binUI))
	    binUI->SetNeedsWidthRecalc (True);

	// if asset is selected, deselect it and remove it from selection list
	if (asset->IsSelected ())
	{
	    asset->SetSelect (False);
	    fAssetBase->NotifySelect (asset);
	}

	// disassociate the assetUI from the asset
	asset->SetClientData (this, NULL);

	// delete the assetUI
	delete assetUI;

	if (!suspended)
	    fView->ListUpdateUI ();
    }
}


//
// Called by asset base's client dispatch routine to
// notify clients of a selected asset.
//
void
AeBinEditor::SelectAsset (AeAsset * asset, Boolean suspended)
{
    AeAssetUI * assetUI;

    assert (asset);

    if (asset->GetClientData (this, (void **)&assetUI))
    {
	if (asset->IsSelected ())
	    fSelectionList->Append (assetUI);
	else
	    fSelectionList->Remove (assetUI);

	if (!suspended && fView->ListAssetInView (asset))
	    fView->ListSelectRow (assetUI->GetRow (), asset->IsSelected ()); 
    }
}


//
// Called by asset base's client dispatch routine to
// notify clients that the asset online status with a player
// has changed.
//
void
AeBinEditor::OnlineAsset (AeAsset * asset, Boolean suspended)
{
    if (!suspended && fView->ListAssetInView (asset))
	fView->ListRedraw ();
}


void
AeBinEditor::UpdateResume (void)
{
    fView->ListUpdateUI ();
}


//
// There are several ways to update the UI corresponding to
// the given asset.  The method used below is relatively
// straightforward and is list widget based as opposed to
// editor based.  This makes sense since we need to update only
// the assets that are in the current view and only the view's
// list widget knows who is in the view and where it is.  This
// information is not directly stored in the editor so we would have
// to recursively descend through the assetUI hierarchy to find the
// location of the assetUI in the list cell matrix.  We could
// store this information directly in the assetUI objects but
// they would need to store both the row index and whether or
// not the assetUI is actually being displayed.  Managing this
// is not worth the editor's time so just have the widget be in charge.
//
void
AeBinEditor::updateAsset (AeAsset * asset)
{
    AeAssetBinUI *	binUI;
    AeAssetUI *		assetUI;
    Widget		list;
    int			numRows;
    int			row;

    assert (fView);
    list = fView->ListGetWidget ();

    assert (list);
    numRows = XbaeMatrixNumRows (list);

    for (row=0; row<numRows; row++)
    {
	assetUI = (AeAssetUI *)XbaeMatrixGetRowUserData (list, row);
	
	if (assetUI->GetAsset () == asset)
	{
	    if (FindTypedBinUI (asset->GetType (), binUI))
		binUI->UpdateAssetUIFields (fView, assetUI, row);
	}
    }
}


void
AeBinEditor::updateWidths (void)
{
    GList<AeFieldUI *> *	fieldUIList;
    AeFieldUI *			fieldUI;
    int				i;

    fieldUIList = fBinUI->GetFieldUIList ();

    fieldUIList->Start (i);

    while (fieldUIList->Next (i, fieldUI))
    {
	if (fieldUI->NeedsWidthUpdate ())
	{
	    fView->ListUpdateUIWidths ();
	    break;
	}

    }
}


Boolean
AeBinEditor::FindTypedBinUI (TAssetType type, AeAssetBinUI* & binUI)
{
    int i;

    fBinUIList->Start (i);

    while (fBinUIList->Next (i, binUI))
	if (type == binUI->GetType ())
	    return True;

    return False;
}