Exemplo n.º 1
0
void CtrlTree::handleEvent( EvtGeneric &rEvent )
{
    bool bChangedPosition = false;
    VarTree::Iterator toShow; bool needShow = false;
    if( rEvent.getAsString().find( "key:down" ) != string::npos )
    {
        int key = ((EvtKey&)rEvent).getKey();
        VarTree::Iterator it;
        bool previousWasSelected = false;

        /* Delete the selection */
        if( key == KEY_DELETE )
        {
            /* Find first non selected item before m_pLastSelected */
            VarTree::Iterator it_sel = m_flat ? m_rTree.firstLeaf()
                                              : m_rTree.begin();
            for( it = (m_flat ? m_rTree.firstLeaf() : m_rTree.begin());
                 it != m_rTree.end();
                 it = (m_flat ? m_rTree.getNextLeaf( it )
                              : m_rTree.getNextVisibleItem( it )) )
            {
                if( &*it == m_pLastSelected ) break;
                if( !it->isSelected() ) it_sel = it;
            }

            /* Delete selected stuff */
            m_rTree.delSelected();

            /* Verify if there is still sthg selected (e.g read-only items) */
            m_pLastSelected = NULL;
            for( it = (m_flat ? m_rTree.firstLeaf() : m_rTree.begin());
                 it != m_rTree.end();
                 it = (m_flat ? m_rTree.getNextLeaf( it )
                              : m_rTree.getNextVisibleItem( it )) )
            {
                if( it->isSelected() )
                    m_pLastSelected = &*it;
            }

            /* if everything was deleted, use it_sel as last selection */
            if( !m_pLastSelected )
            {
                it_sel->setSelected( true );
                m_pLastSelected = &*it_sel;
            }

            // Redraw the control
            makeImage();
            notifyLayout();
        }
        else if( key == KEY_PAGEDOWN )
        {
            it = m_firstPos;
            int i = (int)(maxItems()*1.5);
            while( i >= 0 )
            {
                VarTree::Iterator it_old = it;
                it = m_flat ? m_rTree.getNextLeaf( it )
                            : m_rTree.getNextVisibleItem( it );
                /* End is already visible, dont' scroll */
                if( it == m_rTree.end() )
                {
                    it = it_old;
                    break;
                }
                needShow = true;
                i--;
            }
            if( needShow )
            {
                ensureVisible( it );
                makeImage();
                notifyLayout();
            }
        }
        else if (key == KEY_PAGEUP )
        {
            it = m_firstPos;
            int i = maxItems();
            while( i >= maxItems()/2 )
            {
                it = m_flat ? m_rTree.getPrevLeaf( it )
                            : m_rTree.getPrevVisibleItem( it );
                /* End is already visible, dont' scroll */
                if( it == ( m_flat ? m_rTree.firstLeaf() : m_rTree.begin() ) )
                {
                    break;
                }
                i--;
            }
            ensureVisible( it );
            makeImage();
            notifyLayout();
        }
        else if ( key == KEY_UP ||
                  key == KEY_DOWN ||
                  key == KEY_LEFT ||
                  key == KEY_RIGHT ||
                  key == KEY_ENTER ||
                  key == ' ' )
        {
            for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
                 it != m_rTree.end();
                 it = m_flat ? m_rTree.getNextLeaf( it )
                             : m_rTree.getNextVisibleItem( it ) )
            {
                VarTree::Iterator next = m_flat ?
                                         m_rTree.getNextLeaf( it ) :
                                         m_rTree.getNextVisibleItem( it );
                if( key == KEY_UP )
                {
                    // Scroll up one item
                    if( ( it->parent()
                          && it != it->parent()->begin() )
                        || &*it != m_pLastSelected )
                    {
                        bool nextWasSelected = ( &*next == m_pLastSelected );
                        it->setSelected( nextWasSelected );
                        if( nextWasSelected )
                        {
                            m_pLastSelected = &*it;
                            needShow = true; toShow = it;
                        }
                    }
                }
                else if( key == KEY_DOWN )
                {
                    // Scroll down one item
                    if( ( it->parent()
                          && next != it->parent()->end() )
                        || &*it != m_pLastSelected )
                    {
                        it->setSelected( previousWasSelected );
                    }
                    if( previousWasSelected )
                    {
                        m_pLastSelected = &*it;
                        needShow = true; toShow = it;
                        previousWasSelected = false;
                    }
                    else
                    {
                        previousWasSelected = ( &*it == m_pLastSelected );
                    }

                    // Fix last tree item selection
                    if( ( m_flat ? m_rTree.getNextLeaf( it )
                        : m_rTree.getNextVisibleItem( it ) ) == m_rTree.end()
                     && &*it == m_pLastSelected )
                    {
                        it->setSelected( true );
                    }
                }
                else if( key == KEY_RIGHT )
                {
                    // Go down one level (and expand node)
                    if( &*it == m_pLastSelected )
                    {
                        if( it->isExpanded() )
                        {
                            if( it->size() )
                            {
                                it->setSelected( false );
                                it->begin()->setSelected( true );
                                m_pLastSelected = &*(it->begin());
                            }
                            else
                            {
                                m_rTree.action( &*it );
                            }
                        }
                        else
                        {
                            it->setExpanded( true );
                            bChangedPosition = true;
                        }
                    }
                }
                else if( key == KEY_LEFT )
                {
                    // Go up one level (and close node)
                    if( &*it == m_pLastSelected )
                    {
                        if( it->isExpanded() && it->size() )
                        {
                            it->setExpanded( false );
                            bChangedPosition = true;
                        }
                        else
                        {
                            if( it->parent() && it->parent() != &m_rTree)
                            {
                                it->setSelected( false );
                                m_pLastSelected = it->parent();
                                m_pLastSelected->setSelected( true );
                            }
                        }
                    }
                }
                else if( key == KEY_ENTER || key == ' ' )
                {
                    // Go up one level (and close node)
                    if( &*it == m_pLastSelected )
                    {
                        m_rTree.action( &*it );
                    }
                }
            }
            if( needShow )
                ensureVisible( toShow );
            // Redraw the control
            makeImage();
            notifyLayout();
        }
        else
        {
            // other keys to be forwarded to vlc core
            EvtKey& rEvtKey = (EvtKey&)rEvent;
            var_SetInteger( getIntf()->p_libvlc, "key-pressed",
                            rEvtKey.getModKey() );
        }

    }

    else if( rEvent.getAsString().find( "mouse:left" ) != string::npos )
    {
        EvtMouse &rEvtMouse = (EvtMouse&)rEvent;
        const Position *pos = getPosition();
        int yPos = ( rEvtMouse.getYPos() - pos->getTop() ) / itemHeight();
        int xPos = rEvtMouse.getXPos() - pos->getLeft();
        VarTree::Iterator it;

        if( rEvent.getAsString().find( "mouse:left:down:ctrl,shift" ) !=
            string::npos )
        {
            VarTree::Iterator itClicked = findItemAtPos( yPos );
            // Flag to know if the current item must be selected
            bool select = false;
            for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
                 it != m_rTree.end();
                 it = m_flat ? m_rTree.getNextLeaf( it )
                             : m_rTree.getNextVisibleItem( it ) )
            {
                bool nextSelect = select;
                if( it == itClicked || &*it == m_pLastSelected )
                {
                    if( select )
                    {
                        nextSelect = false;
                    }
                    else
                    {
                        select = true;
                        nextSelect = true;
                    }
                }
                it->setSelected( it->isSelected() || select );
                select = nextSelect;
            }
            // Redraw the control
            makeImage();
            notifyLayout();
        }
        else if( rEvent.getAsString().find( "mouse:left:down:ctrl" ) !=
                 string::npos )
        {
            // Invert the selection of the item
            it = findItemAtPos( yPos );
            if( it != m_rTree.end() )
            {
                it->toggleSelected();
                m_pLastSelected = &*it;
            }
            // Redraw the control
            makeImage();
            notifyLayout();
        }
        else if( rEvent.getAsString().find( "mouse:left:down:shift" ) !=
                 string::npos )
        {
            VarTree::Iterator itClicked = findItemAtPos( yPos );
            // Flag to know if the current item must be selected
            bool select = false;
            for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
                 it != m_rTree.end();
                 it = m_flat ? m_rTree.getNextLeaf( it )
                             : m_rTree.getNextVisibleItem( it ) )
            {
                bool nextSelect = select;
                if( it == itClicked || &*it == m_pLastSelected )
                {
                    if( select )
                    {
                        nextSelect = false;
                    }
                    else
                    {
                        select = true;
                        nextSelect = true;
                    }
                }
                it->setSelected( select );
                select = nextSelect;
            }
            // Redraw the control
            makeImage();
            notifyLayout();
        }
        else if( rEvent.getAsString().find( "mouse:left:down" ) !=
                 string::npos )
        {
            it = findItemAtPos(yPos);
            if( it != m_rTree.end() )
            {
                if( ( it->size() && xPos > (it->depth() - 1) * itemImageWidth()
                      && xPos < it->depth() * itemImageWidth() )
                 && !m_flat )
                {
                    // Fold/unfold the item
                    it->toggleExpanded();
                    bChangedPosition = true;
                }
                else
                {
                    // Unselect any previously selected item
                    VarTree::Iterator it2;
                    for( it2 = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
                         it2 != m_rTree.end();
                         it2 = m_flat ? m_rTree.getNextLeaf( it2 )
                                      : m_rTree.getNextVisibleItem( it2 ) )
                    {
                        it2->setSelected( false );
                    }
                    // Select the new item
                    if( it != m_rTree.end() )
                    {
                        it->setSelected( true );
                        m_pLastSelected = &*it;
                    }
                }
            }
            // Redraw the control
            makeImage();
            notifyLayout();
        }
        else if( rEvent.getAsString().find( "mouse:left:dblclick" ) !=
                 string::npos )
        {
            it = findItemAtPos(yPos);
            if( it != m_rTree.end() )
            {
               // Execute the action associated to this item
               m_rTree.action( &*it );
            }
            // Redraw the control
            makeImage();
            notifyLayout();
        }
    }

    else if( rEvent.getAsString().find( "scroll" ) != string::npos )
    {
        // XXX ctrl_slider.cpp has two more (but slightly different)
        // XXX implementations of `scroll'. Figure out where it belongs.

        int direction = static_cast<EvtScroll&>(rEvent).getDirection();

        double percentage = m_rTree.getPositionVar().get();
        double step = 2.0 / (double)( m_flat ? m_rTree.countLeafs()
                                             : m_rTree.visibleItems() );
        if( direction == EvtScroll::kUp )
        {
            percentage += step;
        }
        else
        {
            percentage -= step;
        }
        m_rTree.getPositionVar().set( percentage );
    }

    /* We changed the nodes, let's fix the position var */
    if( bChangedPosition )
    {
        VarTree::Iterator it;
        int iFirst = 0;
        for( it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();
             it != m_rTree.end();
             it = m_flat ? m_rTree.getNextLeaf( it )
                         : m_rTree.getNextVisibleItem( it ) )
        {
            if( it == m_firstPos )
                break;
            iFirst++;
        }

        int indexMax = ( m_flat ? m_rTree.countLeafs()
                                : m_rTree.visibleItems() ) - 1;
        float f_new = (float)iFirst / (float)indexMax;

        m_dontMove = true;
        m_rTree.getPositionVar().set( 1.0 - f_new );
        m_dontMove = false;
    }
}