]> git.sesse.net Git - vlc/blobdiff - modules/gui/skins2/controls/ctrl_slider.cpp
Qt4 - Typo correction.
[vlc] / modules / gui / skins2 / controls / ctrl_slider.cpp
index ba206a8fba52cb709a128dda5b67b21ce291b02d..b7c982926e454b61db8b8c819fa185da7bbe3946 100644 (file)
@@ -1,11 +1,11 @@
 /*****************************************************************************
  * ctrl_slider.cpp
  *****************************************************************************
- * Copyright (C) 2003 VideoLAN
+ * Copyright (C) 2003 the VideoLAN team
  * $Id$
  *
  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
- *          Olivier Teulière <ipkiss@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
@@ -19,7 +19,7 @@
  *
  * 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., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  *****************************************************************************/
 
 #include "ctrl_slider.hpp"
@@ -27,6 +27,7 @@
 #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"
@@ -35,7 +36,7 @@
 
 
 #define RANGE 40
-#define SCROLL_STEP 0.05
+#define SCROLL_STEP 0.05f
 
 
 CtrlSliderCursor::CtrlSliderCursor( intf_thread_t *pIntf,
@@ -50,10 +51,9 @@ CtrlSliderCursor::CtrlSliderCursor( intf_thread_t *pIntf,
     CtrlGeneric( pIntf, rHelp, pVisible ), m_fsm( pIntf ),
     m_rVariable( rVariable ), m_tooltip( rTooltip ),
     m_width( rCurve.getWidth() ), m_height( rCurve.getHeight() ),
-    m_cmdOverDown( this, &transOverDown ),
-    m_cmdDownOver( this, &transDownOver ), m_cmdOverUp( this, &transOverUp ),
-    m_cmdUpOver( this, &transUpOver ), m_cmdMove( this, &transMove ),
-    m_cmdScroll( this, &transScroll ),
+    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 )
 {
@@ -160,114 +160,102 @@ void CtrlSliderCursor::draw( OSGraphics &rImage, int xDest, int yDest )
 }
 
 
-void CtrlSliderCursor::onUpdate( Subject<VarPercent> &rVariable )
+void CtrlSliderCursor::onUpdate( Subject<VarPercent> &rVariable,
+                                 void *arg  )
 {
     // The position has changed
-    notifyLayout( m_rCurve.getWidth(), m_rCurve.getHeight() );
+    refreshLayout();
 }
 
 
-void CtrlSliderCursor::transOverDown( SkinObject *pCtrl )
+void CtrlSliderCursor::CmdOverDown::execute()
 {
-    CtrlSliderCursor *pThis = (CtrlSliderCursor*)pCtrl;
-    EvtMouse *pEvtMouse = (EvtMouse*)pThis->m_pEvt;
+    EvtMouse *pEvtMouse = (EvtMouse*)m_pParent->m_pEvt;
 
     // Compute the resize factors
     float factorX, factorY;
-    pThis->getResizeFactors( factorX, factorY );
+    m_pParent->getResizeFactors( factorX, factorY );
 
     // Get the position of the control
-    const Position *pPos = pThis->getPosition();
+    const Position *pPos = m_pParent->getPosition();
 
     // Compute the offset
     int tempX, tempY;
-    pThis->m_rCurve.getPoint( pThis->m_rVariable.get(), tempX, tempY );
-    pThis->m_xOffset = pEvtMouse->getXPos() - pPos->getLeft()
+    m_pParent->m_rCurve.getPoint( m_pParent->m_rVariable.get(), tempX, tempY );
+    m_pParent->m_xOffset = pEvtMouse->getXPos() - pPos->getLeft()
                        - (int)(tempX * factorX);
-    pThis->m_yOffset = pEvtMouse->getYPos() - pPos->getTop()
+    m_pParent->m_yOffset = pEvtMouse->getYPos() - pPos->getTop()
                        - (int)(tempY * factorY);
 
-    pThis->captureMouse();
-    pThis->m_pImg = pThis->m_pImgDown;
-    pThis->notifyLayout( pThis->m_rCurve.getWidth(),
-                         pThis->m_rCurve.getHeight() );
+    m_pParent->captureMouse();
+    m_pParent->m_pImg = m_pParent->m_pImgDown;
+    m_pParent->refreshLayout();
 }
 
 
-void CtrlSliderCursor::transDownOver( SkinObject *pCtrl )
+void CtrlSliderCursor::CmdDownOver::execute()
 {
-    CtrlSliderCursor *pThis = (CtrlSliderCursor*)pCtrl;
-
     // Save the position
-    pThis->m_lastPercentage = pThis->m_rVariable.get();
+    m_pParent->m_lastPercentage = m_pParent->m_rVariable.get();
 
-    pThis->releaseMouse();
-    pThis->m_pImg = pThis->m_pImgUp;
-    pThis->notifyLayout( pThis->m_rCurve.getWidth(),
-                         pThis->m_rCurve.getHeight() );
+    m_pParent->releaseMouse();
+    m_pParent->m_pImg = m_pParent->m_pImgUp;
+    m_pParent->refreshLayout();
 }
 
 
-void CtrlSliderCursor::transUpOver( SkinObject *pCtrl )
+void CtrlSliderCursor::CmdUpOver::execute()
 {
-    CtrlSliderCursor *pThis = (CtrlSliderCursor*)pCtrl;
-
-    pThis->m_pImg = pThis->m_pImgOver;
-    pThis->notifyLayout( pThis->m_rCurve.getWidth(),
-                         pThis->m_rCurve.getHeight() );
+    m_pParent->m_pImg = m_pParent->m_pImgOver;
+    m_pParent->refreshLayout();
 }
 
 
-void CtrlSliderCursor::transOverUp( SkinObject *pCtrl )
+void CtrlSliderCursor::CmdOverUp::execute()
 {
-    CtrlSliderCursor *pThis = (CtrlSliderCursor*)pCtrl;
-
-    pThis->m_pImg = pThis->m_pImgUp;
-    pThis->notifyLayout( pThis->m_rCurve.getWidth(),
-                         pThis->m_rCurve.getHeight() );
+    m_pParent->m_pImg = m_pParent->m_pImgUp;
+    m_pParent->refreshLayout();
 }
 
 
-void CtrlSliderCursor::transMove( SkinObject *pCtrl )
+void CtrlSliderCursor::CmdMove::execute()
 {
-    CtrlSliderCursor *pThis = (CtrlSliderCursor*)pCtrl;
-    EvtMouse *pEvtMouse = (EvtMouse*)pThis->m_pEvt;
+    EvtMouse *pEvtMouse = (EvtMouse*)m_pParent->m_pEvt;
 
     // Get the position of the control
-    const Position *pPos = pThis->getPosition();
+    const Position *pPos = m_pParent->getPosition();
 
     // Compute the resize factors
     float factorX, factorY;
-    pThis->getResizeFactors( factorX, factorY );
+    m_pParent->getResizeFactors( factorX, factorY );
 
     // Compute the relative position of the centre of the cursor
-    float relX = pEvtMouse->getXPos() - pPos->getLeft() - pThis->m_xOffset;
-    float relY = pEvtMouse->getYPos() - pPos->getTop() - pThis->m_yOffset;
+    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( pThis->m_rCurve.getMinDist( relXPond, relYPond ) < RANGE )
+    if( m_pParent->m_rCurve.getMinDist( relXPond, relYPond ) < RANGE )
     {
-        float percentage = pThis->m_rCurve.getNearestPercent( relXPond,
+        float percentage = m_pParent->m_rCurve.getNearestPercent( relXPond,
                                                               relYPond );
-        pThis->m_rVariable.set( percentage );
+        m_pParent->m_rVariable.set( percentage );
     }
     else
     {
-        pThis->m_rVariable.set( pThis->m_lastPercentage );
+        m_pParent->m_rVariable.set( m_pParent->m_lastPercentage );
     }
 }
 
-void CtrlSliderCursor::transScroll( SkinObject *pCtrl )
+void CtrlSliderCursor::CmdScroll::execute()
 {
-    CtrlSliderCursor *pThis = (CtrlSliderCursor*)pCtrl;
-    EvtScroll *pEvtScroll = (EvtScroll*)pThis->m_pEvt;
+    EvtScroll *pEvtScroll = (EvtScroll*)m_pParent->m_pEvt;
 
     int direction = pEvtScroll->getDirection();
 
-    float percentage = pThis->m_rVariable.get();
+    float percentage = m_pParent->m_rVariable.get();
     if( direction == EvtScroll::kUp )
     {
         percentage += SCROLL_STEP;
@@ -277,7 +265,7 @@ void CtrlSliderCursor::transScroll( SkinObject *pCtrl )
         percentage -= SCROLL_STEP;
     }
 
-    pThis->m_rVariable.set( percentage );
+    m_pParent->m_rVariable.set( percentage );
 }
 
 
@@ -302,15 +290,59 @@ void CtrlSliderCursor::getResizeFactors( float &rFactorX,
 }
 
 
+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, CtrlSliderCursor &rCursor,
+
+CtrlSliderBg::CtrlSliderBg( intf_thread_t *pIntf,
                             const Bezier &rCurve, VarPercent &rVariable,
-                            int thickness, VarBool *pVisible,
-                            const UString &rHelp ):
-    CtrlGeneric( pIntf, rHelp, pVisible ), m_rCursor( rCursor ),
+                            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_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 );
 }
 
 
@@ -320,8 +352,35 @@ bool CtrlSliderBg::mouseOver( int x, int y ) const
     float factorX, factorY;
     getResizeFactors( factorX, factorY );
 
-    return (m_rCurve.getMinDist( (int)(x / factorX),
-                                 (int)(y / factorY) ) < m_thickness );
+    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) );
+        }
+    }
 }
 
 
@@ -347,12 +406,12 @@ void CtrlSliderBg::handleEvent( EvtGeneric &rEvent )
         // Forward the clic to the cursor
         EvtMouse evt( getIntf(), x, y, EvtMouse::kLeft, EvtMouse::kDown );
         TopWindow *pWin = getWindow();
-        if( pWin )
+        if( pWin && m_pCursor )
         {
             EvtEnter evtEnter( getIntf() );
             // XXX It was not supposed to be implemented like that !!
-            pWin->forwardEvent( evtEnter, m_rCursor );
-            pWin->forwardEvent( evt, m_rCursor );
+            pWin->forwardEvent( evtEnter, *m_pCursor );
+            pWin->forwardEvent( evt, *m_pCursor );
         }
     }
     else if( rEvent.getAsString().find( "scroll" ) != string::npos )
@@ -374,6 +433,37 @@ void CtrlSliderBg::handleEvent( EvtGeneric &rEvent )
 }
 
 
+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