⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ctrl_tree.cpp

📁 uclinux 下的vlc播放器源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * ctrl_tree.cpp ***************************************************************************** * Copyright (C) 2003 VideoLAN * $Id: ctrl_tree.cpp 16457 2006-08-31 20:51:12Z hartman $ * * Authors: Antoine Cellerier <dionoea@videolan.org> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/#include <math.h>#include "../utils/var_bool.hpp"#include "ctrl_tree.hpp"#include "../src/os_factory.hpp"#include "../src/os_graphics.hpp"#include "../src/generic_bitmap.hpp"#include "../src/generic_font.hpp"#include "../src/scaled_bitmap.hpp"#include "../utils/position.hpp"#include "../utils/ustring.hpp"#include "../events/evt_key.hpp"#include "../events/evt_mouse.hpp"#include "../events/evt_scroll.hpp"#include "vlc_keys.h"#ifdef sun#   include "solaris_specific.h" // for lrint#endif#define SCROLL_STEP 0.05#define LINE_INTERVAL 1  // Number of pixels inserted between 2 linesCtrlTree::CtrlTree( intf_thread_t *pIntf,                    VarTree &rTree,                    const GenericFont &rFont,                    const GenericBitmap *pBgBitmap,                    const GenericBitmap *pItemBitmap,                    const GenericBitmap *pOpenBitmap,                    const GenericBitmap *pClosedBitmap,                    uint32_t fgColor,                    uint32_t playColor,                    uint32_t bgColor1,                    uint32_t bgColor2,                    uint32_t selColor,                    const UString &rHelp,                    VarBool *pVisible,                    VarBool *pFlat ):    CtrlGeneric( pIntf,rHelp, pVisible), m_rTree( rTree), m_rFont( rFont ),    m_pBgBitmap( pBgBitmap ), m_pItemBitmap( pItemBitmap ),    m_pOpenBitmap( pOpenBitmap ), m_pClosedBitmap( pClosedBitmap ),    m_fgColor( fgColor ), m_playColor( playColor ), m_bgColor1( bgColor1 ),    m_bgColor2( bgColor2 ), m_selColor( selColor ),    m_pLastSelected( NULL ), m_pImage( NULL ), m_dontMove( false ){    // Observe the tree and position variables    m_rTree.addObserver( this );    m_rTree.getPositionVar().addObserver( this );    m_flat = pFlat->get();    m_firstPos = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();    makeImage();}CtrlTree::~CtrlTree(){    m_rTree.getPositionVar().delObserver( this );    m_rTree.delObserver( this );    if( m_pImage )    {        delete m_pImage;    }}int CtrlTree::itemHeight(){    int itemHeight = m_rFont.getSize();    if( !m_flat )    {        if( m_pClosedBitmap )        {            itemHeight = __MAX( m_pClosedBitmap->getHeight(), itemHeight );        }        if( m_pOpenBitmap )        {            itemHeight = __MAX( m_pOpenBitmap->getHeight(), itemHeight );        }    }    if( m_pItemBitmap )    {        itemHeight = __MAX( m_pItemBitmap->getHeight(), itemHeight );    }    itemHeight += LINE_INTERVAL;    return itemHeight;}int CtrlTree::itemImageWidth(){    int bitmapWidth = 5;    if( !m_flat )    {        if( m_pClosedBitmap )        {            bitmapWidth = __MAX( m_pClosedBitmap->getWidth(), bitmapWidth );        }        if( m_pOpenBitmap )        {            bitmapWidth = __MAX( m_pOpenBitmap->getWidth(), bitmapWidth );        }    }    if( m_pItemBitmap )    {        bitmapWidth = __MAX( m_pItemBitmap->getWidth(), bitmapWidth );    }    return bitmapWidth + 2;}int CtrlTree::maxItems(){    const Position *pPos = getPosition();    if( !pPos )    {        return -1;    }    return pPos->getHeight() / itemHeight();}void CtrlTree::onUpdate( Subject<VarTree, tree_update> &rTree,                         tree_update *arg ){    if( arg->i_type == 0 ) // Item update    {        if( arg->b_active_item )        {            autoScroll();            ///\todo We should make image if we are visible in the view            makeImage();        }    }    /// \todo handle delete in a more clever way    else if ( arg->i_type == 1 ) // Global change or deletion    {        m_firstPos = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();        makeImage();    }    else if ( arg->i_type == 2 ) // Item-append    {        if( m_flat && m_firstPos->size() )            m_firstPos = m_rTree.getNextLeaf( m_firstPos );        /// \todo Check if the item is really visible in the view        // (we only check if it in the document)        if( arg->b_visible == true )        {            makeImage();        }    }    else if( arg->i_type == 3 ) // item-del    {        /* Make sure firstPos and lastSelected are still valid */        while( m_firstPos->m_deleted && m_firstPos != m_rTree.root()->begin() )        {            m_firstPos = m_flat ? m_rTree.getPrevLeaf( m_firstPos )                                : m_rTree.getPrevVisibleItem( m_firstPos );        }        if( m_firstPos->m_deleted )            m_firstPos = m_flat ? m_rTree.firstLeaf()                                : m_rTree.root()->begin();        if( arg->b_visible == true )        {            makeImage();        }    }    notifyLayout();}void CtrlTree::onUpdate( Subject<VarPercent> &rPercent, void* arg){    // Determine what is the first item to display    VarTree::Iterator it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();    if( m_dontMove ) return;    int excessItems;    if( m_flat )        excessItems = m_rTree.countLeafs() - maxItems();    else        excessItems = m_rTree.visibleItems() - maxItems();    if( excessItems > 0)    {        VarPercent &rVarPos = m_rTree.getPositionVar();        // a simple (int)(...) causes rounding errors !#ifdef _MSC_VER#   define lrint (int)#endif        if( m_flat )            it = m_rTree.getLeaf(lrint( (1.0 - rVarPos.get()) * (double)excessItems ) + 1 );        else            it = m_rTree.getVisibleItem(lrint( (1.0 - rVarPos.get()) * (double)excessItems ) + 1 );    }    if( m_firstPos != it )    {        // Redraw the control if the position has changed        m_firstPos = it;        makeImage();        notifyLayout();    }}void CtrlTree::onResize(){    // Determine what is the first item to display    VarTree::Iterator it = m_flat ? m_rTree.firstLeaf() : m_rTree.begin();    int excessItems;    if( m_flat )        excessItems = m_rTree.countLeafs() - maxItems();    else        excessItems = m_rTree.visibleItems() - maxItems();    if( excessItems > 0)    {        VarPercent &rVarPos = m_rTree.getPositionVar();        // a simple (int)(...) causes rounding errors !#ifdef _MSC_VER#   define lrint (int)#endif        if( m_flat )            it = m_rTree.getLeaf(lrint( (1.0 - rVarPos.get()) * (double)excessItems ) + 1 );        else            it = m_rTree.getVisibleItem(lrint( (1.0 - rVarPos.get()) * (double)excessItems ) + 1 );    }    // Redraw the control if the position has changed    m_firstPos = it;    makeImage();    notifyLayout();}void CtrlTree::onPositionChange(){    makeImage();    notifyLayout();}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->m_selected ) it_sel = it;            }            /* Delete selected stuff */            m_rTree.delSelected();            /* Select it_sel */            it_sel->m_selected = true;            m_pLastSelected = &*it_sel;        }        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();                return;            }        }        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();            return;        }        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->m_selected = 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).m_selected = 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).m_selected = true;                }            }            else if( key == KEY_RIGHT )            {                // Go down one level (and expand node)                if( &*it == m_pLastSelected )                {                    if( it->m_expanded )                    {                        if( it->size() )                        {                            it->m_selected = false;                            it->begin()->m_selected = true;                            m_pLastSelected = &*(it->begin());                        }                        else                        {                            m_rTree.action( &*it );                        }                    }                    else                    {                        it->m_expanded = true;                        bChangedPosition = true;                    }                }            }            else if( key == KEY_LEFT )            {                // Go up one level (and close node)                if( &*it == m_pLastSelected )                {                    if( it->m_expanded && it->size() )                    {                        it->m_expanded = false;                        bChangedPosition = true;                    }                    else                    {                        if( it->parent() && it->parent() != &m_rTree)                        {                            it->m_selected = false;                            m_pLastSelected = it->parent();                            m_pLastSelected->m_selected = true;                        }                    }                }            }            else if( key == KEY_ENTER || key == KEY_SPACE )            {                // Go up one level (and close node)                if( &*it == m_pLastSelected )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -