void StandardNodeGadget::setEdgeGadget( Edge edge, GadgetPtr gadget )
{
	GadgetPtr previous = getEdgeGadget( edge );
	if( previous == gadget )
	{
		return;
	}

	if( IECore::runTimeCast<Nodule>( gadget ) )
	{
		throw IECore::Exception( "End Gadget can not be a Nodule." );
	}

	LinearContainer *c = noduleContainer( edge );

	GadgetPtr spacer = boost::static_pointer_cast<Gadget>( c->children().back() );
	c->removeChild( spacer );
	if( previous )
	{
		c->removeChild( previous );
	}
	if( gadget )
	{
		c->addChild( gadget );
	}
	c->addChild( spacer );
}
Example #2
0
void NoduleLayout::updateLayout()
{
	// Figure out the order we want to display things in
	// and clear our main container ready for filling in
	// that order.
	vector<GadgetKey> items = layoutOrder();

	LinearContainer *gadgetContainer = noduleContainer();
	gadgetContainer->clearChildren();

	vector<Gadget *> added;
	vector<GadgetPtr> removed;

	// Iterate over the items we need to lay out, creating
	// or reusing gadgets and adding them to the layout.
	for( vector<GadgetKey>::const_iterator it = items.begin(), eIt = items.end(); it != eIt; ++it )
	{
		const GadgetKey &item = *it;
		const IECore::InternedString gadgetType = ::gadgetType( m_parent.get(), *it );

		GadgetPtr gadget;
		GadgetMap::iterator gadgetIt = m_gadgets.find( item );
		if( gadgetIt != m_gadgets.end() && gadgetIt->second.type == gadgetType )
		{
			gadget = gadgetIt->second.gadget;
		}
		else
		{
			// No gadget created yet, or it's the wrong type
			if( item.which() == 0 )
			{
				gadget = Nodule::create( const_cast<Plug *>( boost::get<const Plug *>( item ) ) ); /// \todo Fix cast
			}
			else
			{
				gadget = createCustomGadget( gadgetType, m_parent.get() );
			}

			added.push_back( gadget.get() );
			if( gadgetIt != m_gadgets.end() )
			{
				removed.push_back( gadgetIt->second.gadget );
			}
			m_gadgets[item] = TypeAndGadget( gadgetType, gadget );
		}

		if( gadget )
		{
			gadgetContainer->addChild( gadget );
		}
	}

	// Remove any gadgets we didn't use
	boost::container::flat_set<GadgetKey> itemsSet( items.begin(), items.end() );
	for( GadgetMap::iterator it = m_gadgets.begin(), eIt = m_gadgets.end(); it != eIt; )
	{
		GadgetMap::iterator next = it; ++next;
		if( itemsSet.find( it->first ) == itemsSet.end() )
		{
			removed.push_back( it->second.gadget );
			m_gadgets.erase( it );
		}
		it = next;
	}

	// Let everyone know what we've done.
	/// \todo Maybe we shouldn't know about the NodeGadget?
	if( NodeGadget *nodeGadget = ancestor<NodeGadget>() )
	{
		for( vector<GadgetPtr>::const_iterator it = removed.begin(), eIt = removed.end(); it != eIt; ++it )
		{
			if( Nodule *n = runTimeCast<Nodule>( it->get() ) )
			{
				nodeGadget->noduleRemovedSignal()( nodeGadget, n );
			}
		}

		for( vector<Gadget *>::const_iterator it = added.begin(), eIt = added.end(); it != eIt; ++it )
		{
			if( Nodule *n = runTimeCast<Nodule>( *it ) )
			{
				nodeGadget->noduleAddedSignal()( nodeGadget, n );
			}
		}
	}
}
void StandardNodeGadget::setEdgeGadget( Edge edge, GadgetPtr gadget )
{
	LinearContainer *c = noduleContainer( edge );
	c->removeChild( c->getChild<Gadget>( c->children().size() - 1 ) );
	c->addChild( gadget );
}