Exemplo n.º 1
0
void LayersPanel::DeleteSelectedLayers()
{
    // If anything selected in the grid
    if ( m_Scene && m_Grid->IsAnythingSelected() )
    {
        LayerSelectedItems( false );

        // Begin undo batch
        Undo::BatchCommandPtr batch = new Undo::BatchCommand ();

        // Get an ordered list of the selected rows, and traverse the list in reverse order.
        // This makes sure that removing an item doesn't change the row number of another
        // item that will be removed later in the loop.  If we don't do this, we run the
        // risk of invalidating the selection array as we iterate over it.
        const std::set< uint32_t >& selection = m_Grid->GetSelectedRows();
        std::set< uint32_t >::const_reverse_iterator rowItr = selection.rbegin();
        std::set< uint32_t >::const_reverse_iterator rowEnd = selection.rend();
        for ( ; rowItr != rowEnd; ++rowItr )
        {
            M_LayerDumbPtr::iterator layerItr = m_Layers.find( m_Grid->GetRowName( *rowItr ) );
            HELIUM_ASSERT( layerItr != m_Layers.end() );
            // NOTE: m_Layers is changing as we iterate over the selection (items are being 
            // removed via callbacks), so don't hold on to any iterators that point into the list.  
            // Recalculate m_Layers.end() each time through the loop.
            if ( layerItr != m_Layers.end() )
            {
                Layer* layer = layerItr->second;

                // If the layer that we are about to delete is in the scene's selection list,
                // we had better just clear out the selection list (otherwise the attribute
                // editor will still be showing a layer that is no longer in the scene).  This
                // has to be done before actually deleting the layer.
                if ( m_Scene->GetSelection().Contains( layer ) )
                {
                    batch->Push( m_Scene->GetSelection().Clear() );
                }

                // If the layer has any members, we should remove them before removing the layer,
                // otherwise if those members are deleted, they will be pointing to an invalid
                // layer that will eventually be Disconnected.
                S_SceneNodeSmartPtr descendents = layer->GetDescendants();
                for ( S_SceneNodeSmartPtr::iterator itr = descendents.begin(), end = descendents.end(); itr != end; ++itr )
                {
                    batch->Push( new DependencyCommand( DependencyCommand::Disconnect, layer, *itr ) );
                }

                // Push the command to delete the layer
                batch->Push( new SceneNodeExistenceCommand( Undo::ExistenceActions::Remove, m_Scene, layer ) );
            }
        }

        // End undo batch
        m_Scene->Push( batch );

        m_Scene->Execute( false );
    }
}
Exemplo n.º 2
0
void CurveCreateTool::AddToScene()
{
    if ( !m_Instance.ReferencesObject() )
    {
        return;
    }

    if ( !m_Scene->IsEditable()  )
    {
        return;
    }

    uint32_t countControlPoints = m_Instance->GetNumberControlPoints();
    if ( countControlPoints > 2 ) 
    {
        m_Instance->RemoveControlPointAtIndex( countControlPoints - 1 );
        m_Instance->Evaluate( GraphDirections::Downstream );
    }

    // remove temp reference
    m_Scene->RemoveObject( m_Instance );

    Undo::BatchCommandPtr batch = new Undo::BatchCommand ();

    if ( !m_Created )
    {
        batch->Push( m_Scene->GetSelection().Clear() );
        m_Created = true;
    }

    m_Instance->SetTransient( false );

    for ( OS_HierarchyNodeDumbPtr::Iterator childItr = m_Instance->GetChildren().Begin(), childEnd = m_Instance->GetChildren().End(); childItr != childEnd; ++childItr )
    {
        (*childItr)->SetTransient( false );
    }

    // add the existence of this object to the batch
    batch->Push( new SceneNodeExistenceCommand( Undo::ExistenceActions::Add, m_Scene, m_Instance ) );

    // initialize
    m_Instance->SetOwner( m_Scene );
    m_Instance->Initialize();

    // center origin
    m_Instance->CenterTransform();

    // append instance to selection
    m_Selection.Append( m_Instance );

    // commit the changes
    m_Scene->Push( batch );
    m_Scene->Execute( false );

    m_Instance = NULL;
    CreateInstance( Vector3::Zero );
}
Exemplo n.º 3
0
///////////////////////////////////////////////////////////////////////////////
// Called at the end of a drag-and-drop event.  Called when the user
// releases the mouse button.  Moves all the selected items to be under a 
// new parent (the item that was dropped onto in the tree).  You cannot drop
// onto an item that is already selected (your command will be ignored if
// you do).  All the reparenting is handled through the undo stack so that
// it can be undone and redone.  This function does not update the tree
// hierarchy; that is handled in a callback.
// 
void HierarchyOutliner::OnEndDrag( wxTreeEvent& args )
{
    const wxTreeItemId& dropItem = args.GetItem();

    // You can only drop on a valid item that's not already selected.
    if ( dropItem.IsOk() && !m_TreeCtrl->IsSelected( dropItem ) )
    {
        m_TreeCtrl->Freeze();

        // Reparent every selected item into the item that was dropped on
        SceneGraph::HierarchyNode* newParent = GetTreeItemData( dropItem )->GetHierarchyNode();
        HELIUM_ASSERT( newParent );

        Undo::BatchCommandPtr batch = new Undo::BatchCommand ();

        const OS_SceneNodeDumbPtr& selection = m_CurrentScene->GetSelection().GetItems();
        OS_SceneNodeDumbPtr::Iterator selItr = selection.Begin();
        const OS_SceneNodeDumbPtr::Iterator selEnd = selection.End();
        for ( ; selItr != selEnd; ++selItr )
        {
            SceneGraph::HierarchyNode* hNode = Reflect::ObjectCast< SceneGraph::HierarchyNode >( *selItr );
            if ( hNode )
            {
                batch->Push( new ParentCommand( hNode, newParent ) );
            }
        }

        m_CurrentScene->Push( batch );

        m_TreeCtrl->Thaw();
    }
    // else: drop target was not valid
}
Exemplo n.º 4
0
///////////////////////////////////////////////////////////////////////////////
// Called when the "New Layer From Selection" button is clicked on the toolbar.
// 
void LayersPanel::OnNewLayerFromSelection( wxCommandEvent& dummyEvt )
{
    if ( m_Scene )
    {    
        if(IsSelectionValid() == false)
        {
            return;
        }

        Undo::BatchCommandPtr batch = new Undo::BatchCommand ();
        LayerPtr layer = new Layer();
        layer->SetOwner( m_Scene );
        layer->Initialize();

        // Generate a name for this layer
        GenerateLayerName(layer);

        batch->Push( new SceneNodeExistenceCommand( Undo::ExistenceActions::Add, m_Scene, layer ) );

        // Step 2: add all the selected items to the layer
        const OS_SceneNodeDumbPtr& selection = m_Scene->GetSelection().GetItems();
        OS_SceneNodeDumbPtr::Iterator itr = selection.Begin();
        OS_SceneNodeDumbPtr::Iterator end = selection.End();
        for ( ; itr != end; ++itr )
        {
            //If the element is a supported type
            if( *itr )
            {
                SceneNode* node = Reflect::SafeCast< SceneNode >( *itr );
                if ( node )
                {
                    batch->Push( new DependencyCommand( DependencyCommand::Connect, layer, node ) );
                }
            }
        }

        m_Scene->Push( batch );
        m_Scene->Execute( false );
    }
}
Exemplo n.º 5
0
///////////////////////////////////////////////////////////////////////////////
// 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 );
        }
    }
}