Exemple #1
0
void CtrlTree::makeImage()
{
    stats_TimerStart( getIntf(), "[Skins] Playlist image",
                      STATS_TIMER_SKINS_PLAYTREE_IMAGE );
    delete m_pImage;

    // Get the size of the control
    const Position *pPos = getPosition();
    if( !pPos )
    {
        stats_TimerStop( getIntf(), STATS_TIMER_SKINS_PLAYTREE_IMAGE );
        return;
    }
    int width = pPos->getWidth();
    int height = pPos->getHeight();

    int i_itemHeight = itemHeight();

    // Create an image
    OSFactory *pOsFactory = OSFactory::instance( getIntf() );
    m_pImage = pOsFactory->createOSGraphics( width, height );

    VarTree::Iterator it = m_firstPos;

    if( m_pBgBitmap )
    {
        // Draw the background bitmap
        if( !m_pScaledBitmap ||
            m_pScaledBitmap->getWidth() != width ||
            m_pScaledBitmap->getHeight() != height )
        {
            delete m_pScaledBitmap;
            m_pScaledBitmap =
                new ScaledBitmap( getIntf(), *m_pBgBitmap, width, height );
        }
        m_pImage->drawBitmap( *m_pScaledBitmap, 0, 0 );

        for( int yPos = 0; yPos < height; yPos += i_itemHeight )
        {
            if( it != m_rTree.end() )
            {
                if( it->isSelected() )
                {
                    int rectHeight = __MIN( i_itemHeight, height - yPos );
                    m_pImage->fillRect( 0, yPos, width, rectHeight,
                                        m_selColor );
                }
                do
                {
                    it = m_flat ? m_rTree.getNextLeaf( it )
                                : m_rTree.getNextVisibleItem( it );
                } while( it != m_rTree.end() && it->isDeleted() );
            }
        }
    }
    else
    {
        // FIXME (TRYME)
        // Fill background with background color
        uint32_t bgColor = m_bgColor1;
        m_pImage->fillRect( 0, 0, width, height, bgColor );
        for( int yPos = 0; yPos < height; yPos += i_itemHeight )
        {
            int rectHeight = __MIN( i_itemHeight, height - yPos );
            if( it == m_rTree.end() )
                m_pImage->fillRect( 0, yPos, width, rectHeight, bgColor );
            else
            {
                uint32_t color = ( it->isSelected() ? m_selColor : bgColor );
                m_pImage->fillRect( 0, yPos, width, rectHeight, color );
                do
                {
                    it = m_flat ? m_rTree.getNextLeaf( it )
                                : m_rTree.getNextVisibleItem( it );
                } while( it != m_rTree.end() && it->isDeleted() );
            }
            bgColor = ( bgColor == m_bgColor1 ? m_bgColor2 : m_bgColor1 );
        }
    }

    int bitmapWidth = itemImageWidth();

    int yPos = 0;
    it = m_firstPos;
    while( it != m_rTree.end() && yPos < height )
    {
        const GenericBitmap *m_pCurBitmap;
        UString *pStr = it->getString();
        uint32_t color = ( it->isPlaying() ? m_playColor : m_fgColor );

        // Draw the text
        if( pStr != NULL )
        {
            int depth = m_flat ? 1 : it->depth();
            GenericBitmap *pText = m_rFont.drawString( *pStr, color, width - bitmapWidth * depth );
            if( !pText )
            {
                stats_TimerStop( getIntf(), STATS_TIMER_SKINS_PLAYTREE_IMAGE );
                return;
            }
            if( it->size() )
                m_pCurBitmap = it->isExpanded() ? m_pOpenBitmap : m_pClosedBitmap;
            else
                m_pCurBitmap = m_pItemBitmap;

            if( m_pCurBitmap )
            {
                // Make sure we are centered on the line
                int yPos2 = yPos+(i_itemHeight-m_pCurBitmap->getHeight()+1)/2;
                if( yPos2 >= height )
                {
                    delete pText;
                    break;
                }
                m_pImage->drawBitmap( *m_pCurBitmap, 0, 0,
                                      bitmapWidth * (depth - 1 ), yPos2,
                                      m_pCurBitmap->getWidth(),
                                      __MIN( m_pCurBitmap->getHeight(),
                                             height -  yPos2), true );
            }
            yPos += i_itemHeight - pText->getHeight();
            int ySrc = 0;
            if( yPos < 0 )
            {
                ySrc = - yPos;
                yPos = 0;
            }
            int lineHeight = __MIN( pText->getHeight() - ySrc, height - yPos );
            m_pImage->drawBitmap( *pText, 0, ySrc, bitmapWidth * depth, yPos,
                                  pText->getWidth(),
                                  lineHeight, true );
            yPos += (pText->getHeight() - ySrc );
            delete pText;
        }
        do
        {
            it = m_flat ? m_rTree.getNextLeaf( it )
                : m_rTree.getNextVisibleItem( it );
        } while( it != m_rTree.end() && it->isDeleted() );
    }
    stats_TimerStop( getIntf(), STATS_TIMER_SKINS_PLAYTREE_IMAGE );
}
Exemple #2
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;
    }
}