Beispiel #1
0
///////////////////////////////////////////////////////////////////////////////
// Called when the "Select Layer Members" button is clicked on the toolbar.
//
void LayersPanel::OnSelectLayerMembers( wxCommandEvent& event )
{
    if ( m_Scene )
    {
        OS_SceneNodeDumbPtr newSelection;
        M_LayerDumbPtr::const_iterator layerItr = m_Layers.begin();
        M_LayerDumbPtr::const_iterator layerEnd = m_Layers.end();
        for ( ; layerItr != layerEnd; ++layerItr )
        {
            Layer* layer = layerItr->second;
            if ( m_Grid->IsSelected( layer->GetName() ) )
            {
                S_SceneNodeSmartPtr::const_iterator dependItr = layer->GetDescendants().begin();
                S_SceneNodeSmartPtr::const_iterator dependEnd = layer->GetDescendants().end();
                for ( ; dependItr != dependEnd; ++dependItr )
                {
                    newSelection.Append( *dependItr );
                }
            }
        }

        m_Scene->Push( m_Scene->GetSelection().SetItems( newSelection ) );
        m_Scene->Execute( false );
    }
}
Beispiel #2
0
///////////////////////////////////////////////////////////////////////////////
// Callback for when a selection change has been completed by a user interaction.
// Updates the scene selection to match that of the tree.
// 
void SceneOutliner::OnSelectionChanged( wxTreeEvent& args )
{
    EDITOR_SCOPE_TIMER( ("") );

    if ( m_CurrentScene && !m_IgnoreSelectionChange )
    {
        OS_SceneNodeDumbPtr nodes;

        wxArrayTreeItemIds selections;
        const size_t numSelections = m_TreeCtrl->GetSelections( selections );
        for ( size_t i = 0; i < numSelections; i++ )
        {
            SceneOutlinerItemData* itemData = GetTreeItemData( selections[i] );
            if ( itemData )
            {
                SceneNode* node = Reflect::SafeCast<SceneNode>( itemData->GetObject() );
                if ( node )
                {
                    nodes.Append( node );
                }
            }
        }  

        // Set the selection on the scene.  Note, the second parameter is a delegate that
        // tells the scene selection event not to pass the event back to this class since
        // we have already updated ourselves.
        m_CurrentScene->Push( m_CurrentScene->GetSelection().SetItems( nodes, SelectionChangingSignature::Delegate (), SelectionChangedSignature::Delegate( this, &SceneOutliner::SelectionChanged ) ) );
    }
}
Beispiel #3
0
///////////////////////////////////////////////////////////////////////////////
// Callback for when a row's selectability checkbox is changed in the grid.
// Changes the selectability member of the layer to match the row that was
// changed.
// 
void LayersPanel::LayerSelectableChanged( const GridRowChangeArgs& args )
{
    const tstring& name = m_Grid->GetRowName( args.m_RowNumber );
    M_LayerDumbPtr::const_iterator layerItr = m_Layers.find( name );
    if ( layerItr != m_Layers.end() )
    {
        Layer* layer = layerItr->second;
        bool selectable = m_Grid->IsRowSelectableChecked( args.m_RowNumber );

        layer->SetSelectable( selectable );

        if (!selectable)
        {
            OS_SceneNodeDumbPtr newSelection;

            OS_SceneNodeDumbPtr selection = layer->GetOwner()->GetSelection().GetItems();
            OS_SceneNodeDumbPtr::Iterator itr = selection.Begin();
            OS_SceneNodeDumbPtr::Iterator end = selection.End();
            for ( ; itr != end; ++itr )
            {
                SceneNode* node = Reflect::SafeCast<SceneNode>( *itr );

                if (!node || !layer->ContainsMember( node ))
                {
                    newSelection.Append(*itr);
                }
            }

            if (newSelection.Size() != selection.Size())
            {
                layer->GetOwner()->GetSelection().SetItems( newSelection );
            }
        }

        layer->GetOwner()->Execute( false );
    }
    else
    {
        Log::Error( TXT( "LayerSelectableChanged - layer named %s not found\n" ), name.c_str() );
        HELIUM_BREAK();
    }
}
Beispiel #4
0
///////////////////////////////////////////////////////////////////////////////
// Called when the "Select Layer" button is clicked on the toolbar.  Goes
// through all the layers that are currently selected in this control and
// adds them to the scene's selection list (implicity this is an undoable
// operation).
//
void LayersPanel::OnSelectLayer( wxCommandEvent& event )
{
    if ( m_Scene )
    {
        OS_SceneNodeDumbPtr newSelection;

        const std::set< uint32_t >& selection = m_Grid->GetSelectedRows();
        std::set< uint32_t >::const_iterator rowItr = selection.begin();
        std::set< uint32_t >::const_iterator rowEnd = selection.end();
        for ( ; rowItr != rowEnd; ++rowItr )
        {
            M_LayerDumbPtr::iterator layerItr = m_Layers.find( m_Grid->GetRowName( *rowItr ) );
            HELIUM_ASSERT( layerItr != m_Layers.end() );
            Layer* layer = layerItr->second;
            newSelection.Append( layer );
        }

        m_Scene->Push( m_Scene->GetSelection().SetItems( newSelection ) );
        m_Scene->Execute( false );
    }
}
Beispiel #5
0
void PropertiesManager::GenerateProperties( PropertiesThreadArgs& args )
{
    M_ElementByType currentElements;
    M_ElementsByType commonElements;
    M_InterpretersByType commonElementInterpreters;
    EnumerateElementArgs enumerateElementArgs( currentElements, commonElements, commonElementInterpreters );
    OS_SceneNodeDumbPtr selection;

    for ( OrderedSet<SceneNodePtr>::Iterator itr = args.m_Selection.Begin(), end = args.m_Selection.End(); itr != end; ++itr )
    {
        selection.Append( *itr );
    }

    //
    // First Pass:
    //  Iterates over selection, asking each to enumerate their attributes into temp members (current)
    //  Then coallate those results into an intersection member (common)
    //

    HELIUM_ASSERT( !selection.Empty() );

    // intersection support
    M_PanelCreators intersectingPanels = s_PanelCreators;

    // union support
    typedef std::map< tstring, OS_SceneNodeDumbPtr > M_UnionedSelections;
    M_UnionedSelections unionedSelections;
    M_PanelCreators unionedPanels;

    {
        SCENE_GRAPH_SCOPE_TIMER( ("Selection Processing") );

        OS_SceneNodeDumbPtr::Iterator itr = selection.Begin();
        OS_SceneNodeDumbPtr::Iterator end = selection.End();
        for ( size_t index = 0; itr != end; ++itr, ++index )
        {
            if ( *args.m_CurrentSelectionId != args.m_SelectionId )
            {
                return;
            }

            currentElements.clear();

            {
                SCENE_GRAPH_SCOPE_TIMER( ("Object Property Enumeration") );

                (*itr)->ConnectProperties(enumerateElementArgs);
            }

            M_PanelCreators currentPanels;

#ifdef SCENE_DEBUG_PROPERTIES_GENERATOR
            Log::Print("Object type %s:\n", (*itr)->GetClass()->m_Name.c_str() );
#endif

            {
                SCENE_GRAPH_SCOPE_TIMER( ("Object Panel Validation") );

                M_PanelCreators::const_iterator itrPanel = args.m_Style == PropertiesStyles::Intersection ? intersectingPanels.begin() : s_PanelCreators.begin();
                M_PanelCreators::const_iterator endPanel = args.m_Style == PropertiesStyles::Intersection ? intersectingPanels.end() : s_PanelCreators.end();
                for ( ; itrPanel != endPanel; ++itrPanel)
                {
                    if ( *args.m_CurrentSelectionId != args.m_SelectionId )
                    {
                        return;
                    }

                    if ((*itr)->ValidatePanel(itrPanel->first))
                    {
#ifdef SCENE_DEBUG_PROPERTIES_GENERATOR
                        Log::Print(" accepts %s\n", itrPanel->first.c_str());
#endif
                        switch (m_Style)
                        {
                        case PropertiesStyles::Intersection:
                            {
                                currentPanels.insert( *itrPanel );
                                break;
                            }

                        case PropertiesStyles::Union:
                            {
                                unionedPanels.insert( *itrPanel );

                                Helium::StdInsert<M_UnionedSelections>::Result inserted = 
                                    unionedSelections.insert( M_UnionedSelections::value_type ( itrPanel->first, OS_SceneNodeDumbPtr () ) );

                                inserted.first->second.Append( *itr );
                            }
                        }
                    }
                    else
                    {
#ifdef SCENE_DEBUG_PROPERTIES_GENERATOR
                        Log::Print(" rejects %s\n", itrPanel->first.c_str());
#endif
                    }
                }
            }

#ifdef SCENE_DEBUG_PROPERTIES_GENERATOR
            Log::Print("\n");
#endif

            if ( m_Style == PropertiesStyles::Intersection )
            {
                intersectingPanels = currentPanels;
            }

            if (currentElements.empty())
            {
                commonElements.clear();
            }
            else
            {
                SCENE_GRAPH_SCOPE_TIMER( ("Object Unique Reflect Property Culling") );

                M_ElementsByType newCommonElements;

                if (index == 0)
                {
                    M_ElementByType::const_iterator currentItr = currentElements.begin();
                    M_ElementByType::const_iterator currentEnd = currentElements.end();
                    for ( ; currentItr != currentEnd; ++currentItr )
                    {
                        if ( *args.m_CurrentSelectionId != args.m_SelectionId )
                        {
                            return;
                        }

                        // copy the shared list into the new shared map
                        Helium::StdInsert<M_ElementsByType>::Result inserted = 
                            newCommonElements.insert(M_ElementsByType::value_type( currentItr->first, std::vector<Reflect::Object*> () ));

                        // add this current element's instance to the new shared list
                        inserted.first->second.push_back(currentItr->second);
                    }
                }
                else
                {
                    M_ElementsByType::const_iterator sharedItr = commonElements.begin();
                    M_ElementsByType::const_iterator sharedEnd = commonElements.end();
                    for ( ; sharedItr != sharedEnd; ++sharedItr )
                    {
                        if ( *args.m_CurrentSelectionId != args.m_SelectionId )
                        {
                            return;
                        }

                        M_ElementByType::const_iterator found = currentElements.find(sharedItr->first);

                        // if we found a current element entry for this shared element
                        if (found != currentElements.end())
                        {
                            // copy the shared list into the new shared map
                            Helium::StdInsert<M_ElementsByType>::Result inserted = 
                                newCommonElements.insert(M_ElementsByType::value_type( sharedItr->first, sharedItr->second ));

                            // add this current element's instance to the new shared list
                            inserted.first->second.push_back(found->second);
                        }
                        else
                        {
                            // there is NO instance of this element in the current instance, let it be culled from the shared list
                        }
                    }
                }

                commonElements = newCommonElements;
            }

            // we have eliminated all the shared types, abort
            if (intersectingPanels.empty() && commonElements.empty() )
            {
                break;
            }
        }
    }


    //
    // Second Pass:
    //  Create client-constructed attribute panels
    //

    Inspect::ContainerPtr container = new Inspect::Container ();

    {
        SCENE_GRAPH_SCOPE_TIMER( ("Static Panel Creation") );

        M_PanelCreators::const_iterator itr = args.m_Style == PropertiesStyles::Intersection ? intersectingPanels.begin() : unionedPanels.begin();
        M_PanelCreators::const_iterator end = args.m_Style == PropertiesStyles::Intersection ? intersectingPanels.end() : unionedPanels.end();
        for ( ; itr != end; ++itr )
        {
            if ( *args.m_CurrentSelectionId != args.m_SelectionId )
            {
                return;
            }

            switch ( args.m_Style )
            {
            case PropertiesStyles::Intersection:
                {
                    m_Generator->Push( container );
                    itr->second.Invoke( CreatePanelArgs (m_Generator, selection) );
                    m_Generator->Pop( false );
                    break;
                }

            case PropertiesStyles::Union:
                {
                    M_UnionedSelections::const_iterator found = unionedSelections.find( itr->first );

                    if (found != unionedSelections.end())
                    {
                        // this connects the invocation with the validated selection
                        m_Generator->Push( container );
                        itr->second.Invoke( CreatePanelArgs (m_Generator, found->second) );
                        m_Generator->Pop( false );
                    }
                    else
                    {
                        // something is horribly horribly wrong
                        HELIUM_BREAK();
                    }

                    break;
                }
            }

            // if you hit then, then your custom panel creator needs work
            HELIUM_ASSERT(m_Generator->GetContainerStack().empty());
        }
    }


    //
    // Third Pass:
    //  Iterates over resultant map and causes interpretation to occur for each object in the list
    //

    {
        SCENE_GRAPH_SCOPE_TIMER( ("Reflect Interpret") );

        M_ElementsByType::const_iterator itr = commonElements.begin();
        M_ElementsByType::const_iterator end = commonElements.end();
        for ( ; itr != end; ++itr )
        {
            if ( *args.m_CurrentSelectionId != args.m_SelectionId )
            {
                return;
            }

            Inspect::ReflectInterpreterPtr interpreter = m_Generator->CreateInterpreter<Inspect::ReflectInterpreter>( container );

            interpreter->Interpret(itr->second, itr->first.m_IncludeFlags, itr->first.m_ExcludeFlags);

            Helium::StdInsert<M_InterpretersByType>::Result inserted = 
                commonElementInterpreters.insert( M_InterpretersByType::value_type(itr->first, interpreter) );
        }
    }

    class Presenter
    {
    public:
        Presenter( PropertiesManager* propertiesManager, uint32_t selectionId, const Inspect::V_Control& controls ) 
            : m_PropertiesManager( propertiesManager )
            , m_SelectionId( selectionId )
            , m_Controls( controls )
        { 
        }

        void Finalize( Helium::Void )
        {
            m_PropertiesManager->Present( m_SelectionId, m_Controls );
            delete this;
        }

    private:
        PropertiesManager*  m_PropertiesManager;
        uint32_t                 m_SelectionId;
        Inspect::V_Control  m_Controls;
    };

    // release ownership of the controls now we have passed them onto the main thread for
    //  realization and presentation to the user, this will try and unrealize the controls
    //  from a background thread, but that is okay since they haven't been realized yet :)
    Presenter* presenter = new Presenter ( this, args.m_SelectionId, container->ReleaseChildren() );

    // will cause the main thread to realize and present the controls
    m_CommandQueue->Post( VoidSignature::Delegate( presenter, &Presenter::Finalize ) );
}
Beispiel #6
0
bool CurveEditTool::ValidateSelection( OS_SceneNodeDumbPtr& items )
{
    OS_SceneNodeDumbPtr result;

    OS_SceneNodeDumbPtr::Iterator itr = items.Begin();
    OS_SceneNodeDumbPtr::Iterator end = items.End();
    for( ; itr != end; ++itr )
    {
        CurveControlPoint* p = Reflect::SafeCast<CurveControlPoint>( *itr );

        if ( !p )
        {
            continue;
        }

        bool appendPoint = true;
        if ( s_CurrentSelection )
        {
            appendPoint = false;
            OS_SceneNodeDumbPtr::Iterator curveItr = m_SelectedCurves.Begin();
            OS_SceneNodeDumbPtr::Iterator curveEnd = m_SelectedCurves.End();
            for ( ; curveItr != curveEnd; ++curveItr )
            {
                if ( p->GetParent() == *curveItr )
                {
                    appendPoint = true;
                    break;
                }
            }
        }

        if ( appendPoint )
        {
            result.Append( p );
        }
    }

    items = result;

    if ( items.Empty() )
    {
        OS_SceneNodeDumbPtr::Iterator itr = items.Begin();
        OS_SceneNodeDumbPtr::Iterator end = items.End();
        for( ; itr != end; ++itr )
        {
            Curve* c = Reflect::SafeCast<Curve>( *itr );

            if ( !c )
            {
                continue;
            }

            result.Append( c );
            break;
        }
    }

    items = result;

    return !items.Empty();
}
Beispiel #7
0
void CurveEditTool::KeyPress( const KeyboardInput& e )
{
    if ( !m_Scene->IsEditable() )
    {
        return;
    }

    int32_t keyCode = e.GetKeyCode();

    if ( keyCode == KeyCodes::Left || keyCode == KeyCodes::Up || keyCode == KeyCodes::Right || keyCode == KeyCodes::Down )
    {
        OS_SceneNodeDumbPtr selection = m_Scene->GetSelection().GetItems();

        if ( selection.Empty() )
        {
            return;
        }

        CurveControlPoint* point = Reflect::SafeCast<CurveControlPoint>( selection.Front() );

        if ( !point )
        {
            return;
        }

        Curve* curve = Reflect::SafeCast<Curve>( point->GetParent() );

        if ( !curve )
        {
            return;
        }

        int32_t index =  curve->GetIndexForControlPoint( point );

        if ( index == -1 )
        {
            return;
        }

        uint32_t countControlPoints = curve->GetNumberControlPoints();
        if ( keyCode == KeyCodes::Left || keyCode == KeyCodes::Down )
        {
            index--;
            index += countControlPoints;
            index %= countControlPoints;
        }
        else if ( keyCode == KeyCodes::Right || keyCode == KeyCodes::Up ) 
        {
            index++;
            index %= countControlPoints;
        }

        point = curve->GetControlPointByIndex( index );

        selection.Clear();
        selection.Append( point );
        m_Scene->GetSelection().SetItems( selection );
    }

    Base::KeyPress( e );
}