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

📄 ctrl_slider.cpp

📁 uclinux 下的vlc播放器源代码
💻 CPP
字号:
/***************************************************************************** * ctrl_slider.cpp ***************************************************************************** * Copyright (C) 2003 the VideoLAN team * $Id: ctrl_slider.cpp 16767 2006-09-21 14:32:45Z hartman $ * * Authors: Cyril Deguet     <asmax@via.ecp.fr> *          Olivier Teulière <ipkiss@via.ecp.fr> * * 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 "ctrl_slider.hpp"#include "../events/evt_enter.hpp"#include "../events/evt_mouse.hpp"#include "../events/evt_scroll.hpp"#include "../src/generic_bitmap.hpp"#include "../src/scaled_bitmap.hpp"#include "../src/top_window.hpp"#include "../src/os_factory.hpp"#include "../src/os_graphics.hpp"#include "../utils/position.hpp"#include "../utils/var_percent.hpp"#define RANGE 40#define SCROLL_STEP 0.05fCtrlSliderCursor::CtrlSliderCursor( intf_thread_t *pIntf,                                    const GenericBitmap &rBmpUp,                                    const GenericBitmap &rBmpOver,                                    const GenericBitmap &rBmpDown,                                    const Bezier &rCurve,                                    VarPercent &rVariable,                                    VarBool *pVisible,                                    const UString &rTooltip,                                    const UString &rHelp ):    CtrlGeneric( pIntf, rHelp, pVisible ), m_fsm( pIntf ),    m_rVariable( rVariable ), m_tooltip( rTooltip ),    m_width( rCurve.getWidth() ), m_height( rCurve.getHeight() ),    m_cmdOverDown( this ), m_cmdDownOver( this ),    m_cmdOverUp( this ), m_cmdUpOver( this ),    m_cmdMove( this ), m_cmdScroll( this ),    m_lastPercentage( 0 ), m_xOffset( 0 ), m_yOffset( 0 ),    m_pEvt( NULL ), m_rCurve( rCurve ){    // Build the images of the cursor    OSFactory *pOsFactory = OSFactory::instance( getIntf() );    m_pImgUp = pOsFactory->createOSGraphics( rBmpUp.getWidth(),                                             rBmpUp.getHeight() );    m_pImgUp->drawBitmap( rBmpUp, 0, 0 );    m_pImgDown = pOsFactory->createOSGraphics( rBmpDown.getWidth(),                                               rBmpDown.getHeight() );    m_pImgDown->drawBitmap( rBmpDown, 0, 0 );    m_pImgOver = pOsFactory->createOSGraphics( rBmpOver.getWidth(),                                               rBmpOver.getHeight() );    m_pImgOver->drawBitmap( rBmpOver, 0, 0 );    // States    m_fsm.addState( "up" );    m_fsm.addState( "over" );    m_fsm.addState( "down" );    // Transitions    m_fsm.addTransition( "over", "mouse:left:down", "down",                         &m_cmdOverDown );    m_fsm.addTransition( "down", "mouse:left:up", "over",                         &m_cmdDownOver );    m_fsm.addTransition( "over", "leave", "up", &m_cmdOverUp );    m_fsm.addTransition( "up", "enter", "over", &m_cmdUpOver );    m_fsm.addTransition( "down", "motion", "down", &m_cmdMove );    m_fsm.addTransition( "over", "scroll", "over", &m_cmdScroll );    // Initial state    m_fsm.setState( "up" );    m_pImg = m_pImgUp;    // Observe the position variable    m_rVariable.addObserver( this );    // Initial position of the cursor    m_lastPercentage = m_rVariable.get();}CtrlSliderCursor::~CtrlSliderCursor(){    m_rVariable.delObserver( this );    SKINS_DELETE( m_pImgUp );    SKINS_DELETE( m_pImgDown );    SKINS_DELETE( m_pImgOver );}void CtrlSliderCursor::handleEvent( EvtGeneric &rEvent ){    // Save the event to use it in callbacks    m_pEvt = &rEvent;    m_fsm.handleTransition( rEvent.getAsString() );}bool CtrlSliderCursor::mouseOver( int x, int y ) const{    if( m_pImg )    {        // Compute the position of the cursor        int xPos, yPos;        m_rCurve.getPoint( m_rVariable.get(), xPos, yPos );        // Compute the resize factors        float factorX, factorY;        getResizeFactors( factorX, factorY );        xPos = (int)(xPos * factorX);        yPos = (int)(yPos * factorY);        return m_pImg->hit( x - xPos + m_pImg->getWidth() / 2,                            y - yPos + m_pImg->getHeight() / 2 );    }    else    {        return false;    }}void CtrlSliderCursor::draw( OSGraphics &rImage, int xDest, int yDest ){    if( m_pImg )    {        // Compute the position of the cursor        int xPos, yPos;        m_rCurve.getPoint( m_rVariable.get(), xPos, yPos );        // Compute the resize factors        float factorX, factorY;        getResizeFactors( factorX, factorY );        xPos = (int)(xPos * factorX);        yPos = (int)(yPos * factorY);        // Draw the current image        rImage.drawGraphics( *m_pImg, 0, 0,                             xDest + xPos - m_pImg->getWidth() / 2,                             yDest + yPos - m_pImg->getHeight() / 2 );    }}void CtrlSliderCursor::onUpdate( Subject<VarPercent> &rVariable,                                 void *arg  ){    // The position has changed    refreshLayout();}void CtrlSliderCursor::CmdOverDown::execute(){    EvtMouse *pEvtMouse = (EvtMouse*)m_pParent->m_pEvt;    // Compute the resize factors    float factorX, factorY;    m_pParent->getResizeFactors( factorX, factorY );    // Get the position of the control    const Position *pPos = m_pParent->getPosition();    // Compute the offset    int tempX, tempY;    m_pParent->m_rCurve.getPoint( m_pParent->m_rVariable.get(), tempX, tempY );    m_pParent->m_xOffset = pEvtMouse->getXPos() - pPos->getLeft()                       - (int)(tempX * factorX);    m_pParent->m_yOffset = pEvtMouse->getYPos() - pPos->getTop()                       - (int)(tempY * factorY);    m_pParent->captureMouse();    m_pParent->m_pImg = m_pParent->m_pImgDown;    m_pParent->refreshLayout();}void CtrlSliderCursor::CmdDownOver::execute(){    // Save the position    m_pParent->m_lastPercentage = m_pParent->m_rVariable.get();    m_pParent->releaseMouse();    m_pParent->m_pImg = m_pParent->m_pImgUp;    m_pParent->refreshLayout();}void CtrlSliderCursor::CmdUpOver::execute(){    m_pParent->m_pImg = m_pParent->m_pImgOver;    m_pParent->refreshLayout();}void CtrlSliderCursor::CmdOverUp::execute(){    m_pParent->m_pImg = m_pParent->m_pImgUp;    m_pParent->refreshLayout();}void CtrlSliderCursor::CmdMove::execute(){    EvtMouse *pEvtMouse = (EvtMouse*)m_pParent->m_pEvt;    // Get the position of the control    const Position *pPos = m_pParent->getPosition();    // Compute the resize factors    float factorX, factorY;    m_pParent->getResizeFactors( factorX, factorY );    // Compute the relative position of the centre of the cursor    float relX = pEvtMouse->getXPos() - pPos->getLeft() - m_pParent->m_xOffset;    float relY = pEvtMouse->getYPos() - pPos->getTop() - m_pParent->m_yOffset;    // Ponderate with the resize factors    int relXPond = (int)(relX / factorX);    int relYPond = (int)(relY / factorY);    // Update the position    if( m_pParent->m_rCurve.getMinDist( relXPond, relYPond ) < RANGE )    {        float percentage = m_pParent->m_rCurve.getNearestPercent( relXPond,                                                              relYPond );        m_pParent->m_rVariable.set( percentage );    }    else    {        m_pParent->m_rVariable.set( m_pParent->m_lastPercentage );    }}void CtrlSliderCursor::CmdScroll::execute(){    EvtScroll *pEvtScroll = (EvtScroll*)m_pParent->m_pEvt;    int direction = pEvtScroll->getDirection();    float percentage = m_pParent->m_rVariable.get();    if( direction == EvtScroll::kUp )    {        percentage += SCROLL_STEP;    }    else    {        percentage -= SCROLL_STEP;    }    m_pParent->m_rVariable.set( percentage );}void CtrlSliderCursor::getResizeFactors( float &rFactorX,                                         float &rFactorY ) const{    // Get the position of the control    const Position *pPos = getPosition();    rFactorX = 1.0;    rFactorY = 1.0;    // Compute the resize factors    if( m_width > 0 )    {        rFactorX = (float)pPos->getWidth() / (float)m_width;    }    if( m_height > 0 )    {        rFactorY = (float)pPos->getHeight() / (float)m_height;    }}void CtrlSliderCursor::refreshLayout(){    if( m_pImg )    {        // Compute the resize factors        float factorX, factorY;        getResizeFactors( factorX, factorY );        notifyLayout( (int)(m_rCurve.getWidth() * factorX) + m_pImg->getWidth(),                      (int)(m_rCurve.getHeight() * factorY) + m_pImg->getHeight(),                      - m_pImg->getWidth() / 2,                      - m_pImg->getHeight() / 2 );    }    else        notifyLayout();}CtrlSliderBg::CtrlSliderBg( intf_thread_t *pIntf,                            const Bezier &rCurve, VarPercent &rVariable,                            int thickness, GenericBitmap *pBackground,                            int nbHoriz, int nbVert, int padHoriz, int padVert,                            VarBool *pVisible, const UString &rHelp ):    CtrlGeneric( pIntf, rHelp, pVisible ), m_pCursor( NULL ),    m_rVariable( rVariable ), m_thickness( thickness ), m_rCurve( rCurve ),    m_width( rCurve.getWidth() ), m_height( rCurve.getHeight() ),    m_pImgSeq( pBackground ), m_nbHoriz( nbHoriz ), m_nbVert( nbVert ),    m_padHoriz( padHoriz ), m_padVert( padVert ), m_bgWidth( 0 ),    m_bgHeight( 0 ), m_position( 0 ){    if( pBackground )    {        // Build the background image sequence        // Note: we suppose that the last padding is not included in the        // given image        // TODO: we should probably change this assumption, as it would make        // the code a bit simpler and it would be more natural for the skins        // designers        m_bgWidth = (pBackground->getWidth() + m_padHoriz) / nbHoriz;        m_bgHeight = (pBackground->getHeight() + m_padVert) / nbVert;        // Observe the position variable        m_rVariable.addObserver( this );        // Initial position        m_position = (int)( m_rVariable.get() * (m_nbHoriz * m_nbVert - 1) );    }}CtrlSliderBg::~CtrlSliderBg(){    m_rVariable.delObserver( this );}bool CtrlSliderBg::mouseOver( int x, int y ) const{    // Compute the resize factors    float factorX, factorY;    getResizeFactors( factorX, factorY );    return (m_rCurve.getMinDist( (int)(x / factorX), (int)(y / factorY),                                 factorX, factorY ) < m_thickness );}void CtrlSliderBg::draw( OSGraphics &rImage, int xDest, int yDest ){    if( m_pImgSeq )    {        if( m_bgWidth > 0 && m_bgHeight > 0 )        {            // Compute the resize factors            float factorX, factorY;            getResizeFactors( factorX, factorY );            // Rescale the image with the actual size of the control            ScaledBitmap bmp( getIntf(), *m_pImgSeq,                 m_bgWidth * m_nbHoriz - (int)(m_padHoriz * factorX),                 m_bgHeight * m_nbVert - (int)(m_padVert * factorY) );            // Locate the right image in the background bitmap            int x = m_bgWidth * ( m_position % m_nbHoriz );            int y = m_bgHeight * ( m_position / m_nbHoriz );            // Draw the background image            rImage.drawBitmap( bmp, x, y, xDest, yDest,                               m_bgWidth - (int)(m_padHoriz * factorX),                               m_bgHeight - (int)(m_padVert * factorY) );        }    }}void CtrlSliderBg::handleEvent( EvtGeneric &rEvent ){    if( rEvent.getAsString().find( "mouse:left:down" ) != string::npos )    {        // Compute the resize factors        float factorX, factorY;        getResizeFactors( factorX, factorY );        // Get the position of the control        const Position *pPos = getPosition();        // Get the value corresponding to the position of the mouse        EvtMouse &rEvtMouse = (EvtMouse&)rEvent;        int x = rEvtMouse.getXPos();        int y = rEvtMouse.getYPos();        m_rVariable.set( m_rCurve.getNearestPercent(                            (int)((x - pPos->getLeft()) / factorX),                            (int)((y - pPos->getTop()) / factorY) ) );        // Forward the clic to the cursor        EvtMouse evt( getIntf(), x, y, EvtMouse::kLeft, EvtMouse::kDown );        TopWindow *pWin = getWindow();        if( pWin && m_pCursor )        {            EvtEnter evtEnter( getIntf() );            // XXX It was not supposed to be implemented like that !!            pWin->forwardEvent( evtEnter, *m_pCursor );            pWin->forwardEvent( evt, *m_pCursor );        }    }    else if( rEvent.getAsString().find( "scroll" ) != string::npos )    {        int direction = ((EvtScroll&)rEvent).getDirection();        float percentage = m_rVariable.get();        if( direction == EvtScroll::kUp )        {            percentage += SCROLL_STEP;        }        else        {            percentage -= SCROLL_STEP;        }        m_rVariable.set( percentage );    }}void CtrlSliderBg::onResize(){    if( m_pImgSeq )    {        // Compute only the new size of an elementary image.        // The actual resizing is done in the draw() method for now...        // Compute the resize factors        float factorX, factorY;        getResizeFactors( factorX, factorY );        // Size of one elementary background image (padding included)        m_bgWidth = (int)((m_pImgSeq->getWidth() + m_padHoriz) * factorX / m_nbHoriz);        m_bgHeight = (int)((m_pImgSeq->getHeight() + m_padVert) * factorY / m_nbVert);    }}void CtrlSliderBg::associateCursor( CtrlSliderCursor &rCursor ){    m_pCursor = &rCursor;}void CtrlSliderBg::onUpdate( Subject<VarPercent> &rVariable, void*arg ){    m_position = (int)( m_rVariable.get() * (m_nbHoriz * m_nbVert - 1) );    notifyLayout( m_bgWidth, m_bgHeight );}void CtrlSliderBg::getResizeFactors( float &rFactorX, float &rFactorY ) const{    // Get the position of the control    const Position *pPos = getPosition();    rFactorX = 1.0;    rFactorY = 1.0;    // Compute the resize factors    if( m_width > 0 )    {        rFactorX = (float)pPos->getWidth() / (float)m_width;    }    if( m_height > 0 )    {        rFactorY = (float)pPos->getHeight() / (float)m_height;    }}

⌨️ 快捷键说明

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