AeContainerFieldUI.c++ 3.91 KB
#include <assert.h>
#include <stdio.h>
#include <Vk/VkPopupMenu.h>

#include "GList.h"
#include "AeTypes.h"
#include "AeFieldUI.h"
#include "AeAssetUI.h"
#include "AeAsset.h"
#include "AeAssetBase.h"
#include "AeAssetBin.h"
#include "AeBinEditor.h"
#include "AeBinView.h"



AeContainerFieldUI::AeContainerFieldUI (const char * name,
					Boolean orphansOnly,
					TIntGetProc getProc) : 
    AeFieldUI (name, False, False, False, True, kCenterJustify, 0)
{
    fOrphansOnly = orphansOnly;
    fGetProc = getProc;
    fWidth = kMinWidth;
    fNeedsWidthUpdate = False;
}


AeContainerFieldUI::~AeContainerFieldUI (void)
{
}


void
AeContainerFieldUI::GetValueString (AeAsset * asset, String string)
{
    if (asset->CanContain ())
    {
	int value = fGetProc (asset);
	sprintf (string, "%d", value);
    }
    else
	*string = '\0';
}


void
AeContainerFieldUI::HandleDoubleClick (AeBinEditor * editor,
				       AeAssetUI * assetUI,
				       XEvent * event,
				       TEditModifier modifier)
{
    assert (editor);
    assert (assetUI);

    assetUI->SetOpen (!assetUI->IsOpen ());
    editor->UpdateHierarchy ();
}


Boolean
AeContainerFieldUI::HandleButtonPress (AeBinEditor * editor,
				       AeAssetUI * assetUI,
				       XEvent * event,
				       TEditModifier modifier)
{
    assert (editor);
    assert (assetUI);

    if (modifier == kModMotion)
	return False;

    AeBinEditor::fMenuEditor = editor;
    AeBinEditor::fMenuAssetUI = assetUI;
    AeBinEditor::fMenuFieldUI = this;

    AeBinView * view = editor->GetView ();
    addMenuItems (view->PopupGet (), editor, assetUI);

    view->PopupShow (event);

    return True;
}


void
AeContainerFieldUI::addMenuItems (VkPopupMenu * popup,
				  AeBinEditor * editor,
				  AeAssetUI * parentUI)
{
    AeAssetBin *	parentBin;
    AeAsset *  		parent;

    parent = parentUI->GetAsset ();

    if ((editor->GetAssetBase())->FindTypedBin (parent->GetType (), parentBin))
    {
	GList<AeAsset *> *	childList;
	GList<AeAsset *> *	orphanList;
	AeAssetBin *		orphanBin;
	AeAsset *	       	orphan;
	int	       		i, j;
	Boolean			noOrphans = True;

	assert (parent->CanContain ());
	childList = ((AeContainerAsset *)parent)->GetChildList ();

	orphanBin = parentBin->GetChildBin ();
	orphanList = orphanBin->GetAssetList ();

	// popup->addLabel ("Add Child");
	// popup->addSeparator ();

	// add all the orphans to the menu that are not already
	// children of the asset
	orphanList->Start (i);
	while (orphanList->Next (i, orphan))
	{
	    // if the asset is not already a child of the parent
	    // and if the parent requires an orphan and the asset has no parents
	    // then make the asset avaible in the menu
	    if (!childList->Find (orphan, j) &&
		(!fOrphansOnly || !orphan->HasParent ()))
	    {
		popup->addAction (orphan->GetName (),
				  &AeContainerFieldUI::MenuCallback,
				  (XtPointer)orphan);
		noOrphans = False;
	    }
	}

	if (noOrphans)
	    popup->addLabel ("none available");
    }
}


void
AeContainerFieldUI::MenuCallback (Widget list, XtPointer child, XtPointer callData)
{
    assert (AeBinEditor::fMenuEditor);
    assert (AeBinEditor::fMenuFieldUI);
    assert (AeBinEditor::fMenuAssetUI);
    
    AeContainerFieldUI * fieldUI;

    fieldUI = (AeContainerFieldUI *)AeBinEditor::fMenuFieldUI;
    fieldUI->handleMenuItem (AeBinEditor::fMenuEditor,
			     AeBinEditor::fMenuAssetUI,
			     (AeAsset *)child);
}


void
AeContainerFieldUI::handleMenuItem (AeBinEditor * editor,
				    AeAssetUI * parentUI,
				    AeAsset * child)
{
    assert (parentUI);
    assert (child);

    AeAsset * parent = parentUI->GetAsset ();

    assert (parent);
    assert (parent->CanContain ());

    // append the selected child to the parent and open up the parent
    ((AeContainerAsset *)parent)->AppendChild (child);
    parentUI->SetOpen (True);

    // tell the assetbase that we modified the parent
    (editor->GetAssetBase())->NotifyUpdate (parent);

    // force redraw (hack)
    editor->UpdateHierarchy ();
}