summaryrefslogtreecommitdiffstats
path: root/src/app/slider.cpp
blob: 89b5cedee225f29a248fbba1dd06d916d898d59e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// (c) 2004 Max Howell ([email protected])
// See COPYING file for licensing information

#include "debug.h"
#include "slider.h"
#include <qapplication.h>
#include <qlabel.h>
#include <qsize.h>
#include <qtooltip.h>

#include <qpainter.h>
#include "xineEngine.h"

using Codeine::Slider;


Slider *Slider::s_instance = 0;


Slider::Slider( QWidget *parent, uint max )
      : QSlider( Qt::Horizontal, parent )
      , m_sliding( false )
      , m_outside( false )
      , m_prevValue( 0 )
{
   s_instance = this;

   setRange( 0, max );
   setFocusPolicy( NoFocus );
   setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
}

void
Slider::wheelEvent( QWheelEvent *e )
{
   //if you use this class elsewhere, NOTE this is Codeine specific
   e->ignore(); //pass to VideoWindow
}

void
Slider::mouseMoveEvent( QMouseEvent *e )
{
   if( m_sliding )
   {
      //feels better, but using set value of 20 is bad of course
      QRect rect = this->rect();
      rect.addCoords( -20, -20, 20, 20 );

      if( !rect.contains( e->pos() ) ) {
         if( !m_outside )
            QSlider::setValue( m_prevValue );
         m_outside = true;
      } else {
         m_outside = false;

         QSlider::setValue(
               QRangeControl::valueFromPosition(
                     e->pos().x() - sliderRect().width()/2,
                     width()  - sliderRect().width() ) );

         emit sliderMoved( value() );
      }
   }
   else
      QSlider::mouseMoveEvent( e );
}

void
Slider::mousePressEvent( QMouseEvent *e )
{
   m_sliding   = true;
   m_prevValue = QSlider::value();

   if( !sliderRect().contains( e->pos() ) )
      mouseMoveEvent( e );
}

void
Slider::mouseReleaseEvent( QMouseEvent* )
{
   if( !m_outside && QSlider::value() != m_prevValue )
      emit sliderReleased( value() );

   m_sliding = false;
   m_outside = false;
}

static inline QString timeAsString( const int s )
{
   #define zeroPad( n ) n < 10 ? QString("0%1").arg( n ) : QString::number( n )
   using Codeine::engine;

   const int m  =  s / 60;
   const int h  =  m / 60;

   QString time;
   time.prepend( zeroPad( s % 60 ) ); //seconds
   time.prepend( ':' );
   time.prepend( zeroPad( m % 60 ) ); //minutes
   time.prepend( ':' );
   time.prepend( QString::number( h ) ); //hours

   return time;
}

void
Slider::setValue( int newValue )
{
   static QLabel *w1 = 0;
   static QLabel *w2 = 0;

   if (!w1) {
      w1 = new QLabel( this );
      w1->setPalette( QToolTip::palette() );
      w1->setFrameStyle( QFrame::Plain | QFrame::Box );

      w2 = new QLabel( this );
      w2->setPalette( QToolTip::palette() );
      w2->setFrameStyle( QFrame::Plain | QFrame::Box );
   }

   //TODO stupidly inefficeint! :)
   w1->setShown( mainWindow()->isFullScreen() );
   w2->setShown( mainWindow()->isFullScreen() );


   //don't adjust the slider while the user is dragging it!

   if( !m_sliding || m_outside ) {
      const int l     = engine()->length() / 1000;
      const int left  = int(l * (newValue / 65535.0));
      const int right = l - left;

      QSlider::setValue( newValue );
      w1->move( 0, height() - w1->height() - 1 );
      w1->setText( timeAsString( left ) + ' ' );
      w1->adjustSize();

      w2->move( width() - w2->width(), height() - w1->height() - 1 );
      w2->setText( timeAsString( right ) + ' ' );
      w2->adjustSize();
   }
   else
      m_prevValue = newValue;
}