/////////////////////////////////////////////////////////////////////////////// // Adds undoable commands to m_Scene's undo queue which will do one of two thing: // // Either... // 1. Adds the currently selected scene items to the currently highlighted // layers. Set addToLayer to true for this option. // or... // 2. Removes the currently selected scene items from the currently highlighted // layers. Set addToLayer to false for this option. // // If there are no selected items, or no selected layers, nothing happens. It // is also safe to remove items from a layer even if they are not part of the // layer (nothing happens), or add items to a layer that already belong to // that layer (again, nothing happens). // void LayersPanel::LayerSelectedItems( bool addToLayer ) { HELIUM_ASSERT( m_Scene ); // Decide whether we are adding the selected scene items to the highlighted // layers, or removing the items from the layers. const DependencyCommand::DependencyAction action = addToLayer ? DependencyCommand::Connect : DependencyCommand::Disconnect; // If there are selected nodes in the scene, and selected rows in this control... const OS_SceneNodeDumbPtr& selectedNodes = m_Scene->GetSelection().GetItems(); std::set< uint32_t > selectedRows = m_Grid->GetSelectedRows(); if ( selectedNodes.Size() > 0 && selectedRows.size() > 0 ) { //Log::Debug( "LayerSelectedItems\n" ); Undo::BatchCommandPtr batch = new Undo::BatchCommand (); OS_SceneNodeDumbPtr::Iterator nodeItr = selectedNodes.Begin(); OS_SceneNodeDumbPtr::Iterator nodeEnd = selectedNodes.End(); std::set< uint32_t >::const_iterator rowItr; const std::set< uint32_t >::const_iterator rowEnd = selectedRows.end(); const M_LayerDumbPtr::const_iterator layerEnd = m_Layers.end(); // For each node in the scene's selection list... for ( ; nodeItr != nodeEnd; ++nodeItr ) { // ensure that we are not trying to add one layer to another layer { Layer* layerTest = Reflect::SafeCast< Layer >( *nodeItr ); if( layerTest ) { continue; } } //Check the current selection if( *nodeItr == NULL ) { //Invalid or incompatible continue; } SceneNode* node = Reflect::SafeCast< SceneNode >( *nodeItr ); if ( node ) { // For each row that is highlighted... for ( rowItr = selectedRows.begin(); rowItr != rowEnd; ++rowItr ) { // Find the layer that goes with the highlighted row M_LayerDumbPtr::iterator layerItr = m_Layers.find( m_Grid->GetRowName( *rowItr ) ); if ( layerItr != layerEnd ) { // Check to see if the node is already in the current layer... Layer* layer = layerItr->second; S_SceneNodeSmartPtr::const_iterator foundDescendant = layer->GetDescendants().find( node ); // If the node is already in this layer, and we are suppose to be adding the node to the layer, // just skip the command (doCommand = false). If the node is not in this layer, and we are // suppose to be removing the node from the layer, skip the command as well. Otherwise, go // ahead and carry out the command (doCommand = true). const bool doCommand = addToLayer ? ( foundDescendant == layer->GetDescendants().end() ) : ( foundDescendant != layer->GetDescendants().end() ); if ( doCommand ) { // Finally make an undoable command to add/remove the node to/from the layer batch->Push( new DependencyCommand( action, layer, node ) ); //Log::Debug( "\t\t%s node %s %s layer %s [row=%d]\n", addToLayer ? "Added" : "Removed", node->GetName().c_str(), addToLayer ? "to" : "from", layer->GetName().c_str(), *rowItr ); } else { //Log::Debug( "\t\tNode %s was already a member of layer %s [row=%d]\n", node->GetName().c_str(), layer->GetName().c_str(), *rowItr ); } } else { // Something is wrong. The rows that are selected in the grid do not correspond to // items in our list of layers (m_Layers). Somehow those lists got out of sync. Log::Error( TXT( "Unable to add selection to layer [row=%d] because it doesn't exist\n" ), *rowItr ); HELIUM_BREAK(); } } } } //Log::Debug( "\n" ); if( !batch->IsEmpty() ) { m_Scene->Push( batch ); m_Scene->Execute( false ); } } }