00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "audiowidget.h"
00021 #include "mediaplayerstate.h"
00022
00023
00024 #include <qpe/qpeapplication.h>
00025 #include <qpe/config.h>
00026 #include <opie2/odebug.h>
00027 #include <opie2/oresource.h>
00028
00029
00030 #include <qdir.h>
00031
00032
00033 #include <stdlib.h>
00034 #include <stdio.h>
00035
00036 extern MediaPlayerState *mediaPlayerState;
00037
00038
00039 static const int xo = -2;
00040 static const int yo = 22;
00041
00042 using namespace Opie::Ui;
00043 struct MediaButton {
00044 bool isToggle, isHeld, isDown;
00045 };
00046
00047
00048 MediaButton audioButtons[] = {
00049 { TRUE, FALSE, FALSE },
00050 { FALSE, FALSE, FALSE },
00051 { FALSE, FALSE, FALSE },
00052 { FALSE, FALSE, FALSE },
00053 { FALSE, FALSE, FALSE },
00054 { FALSE, FALSE, FALSE },
00055 { TRUE, FALSE, FALSE },
00056 { FALSE, FALSE, FALSE },
00057 { FALSE, FALSE, FALSE },
00058 { FALSE, FALSE, FALSE }
00059 };
00060
00061 const char *skin_mask_file_names[10] = {
00062 "play", "stop", "next", "prev", "up",
00063 "down", "loop", "playlist", "forward", "back"
00064 };
00065
00066 static void changeTextColor( QWidget *w ) {
00067 QPalette p = w->palette();
00068 p.setBrush( QColorGroup::Background, QColor( 167, 212, 167 ) );
00069 p.setBrush( QColorGroup::Base, QColor( 167, 212, 167 ) );
00070 w->setPalette( p );
00071 }
00072
00073 static const int numButtons = (sizeof(audioButtons)/sizeof(MediaButton));
00074
00075 AudioWidget::AudioWidget(QWidget* parent, const char* name, WFlags f) :
00076 QWidget( parent, name, f ), songInfo( this ), slider( Qt::Horizontal, this ), time( this )
00077 {
00078 setCaption( tr("OpiePlayer") );
00079
00080
00081 Config cfg("OpiePlayer");
00082 cfg.setGroup("Options");
00083 skin = cfg.readEntry("Skin","default");
00084
00085
00086
00087
00088 QString skinPath;
00089 skinPath = "opieplayer2/skins/" + skin;
00090 if(!QDir(QString(getenv("OPIEDIR")) +"/pics/"+skinPath).exists())
00091 skinPath = "opieplayer2/skins/default";
00092
00093
00094
00095 pixBg = new QPixmap( Opie::Core::OResource::loadPixmap( QString("%1/background").arg(skinPath) ) );
00096 imgUp = new QImage( Opie::Core::OResource::loadImage( QString("%1/skin_up").arg(skinPath) ) );
00097 imgDn = new QImage( Opie::Core::OResource::loadImage( QString("%1/skin_down").arg(skinPath) ) );
00098
00099 imgButtonMask = new QImage( imgUp->width(), imgUp->height(), 8, 255 );
00100 imgButtonMask->fill( 0 );
00101
00102 for ( int i = 0; i < 10; i++ ) {
00103 QString filename = QString(getenv("OPIEDIR")) + "/pics/" + skinPath + "/skin_mask_" + skin_mask_file_names[i] + ".png";
00104 masks[i] = new QBitmap( filename );
00105
00106 if ( !masks[i]->isNull() ) {
00107 QImage imgMask = masks[i]->convertToImage();
00108 uchar **dest = imgButtonMask->jumpTable();
00109 for ( int y = 0; y < imgUp->height(); y++ ) {
00110 uchar *line = dest[y];
00111 for ( int x = 0; x < imgUp->width(); x++ )
00112 if ( !qRed( imgMask.pixel( x, y ) ) )
00113 line[x] = i + 1;
00114 }
00115 }
00116
00117 }
00118
00119 for ( int i = 0; i < 11; i++ ) {
00120 buttonPixUp[i] = NULL;
00121 buttonPixDown[i] = NULL;
00122 }
00123
00124 QWidget *d = QApplication::desktop();
00125 int width = d->width();
00126 int height = d->height();
00127
00128 if( (width != pixBg->width() ) || (height != pixBg->height() ) ) {
00129
00130 QImage img;
00131 img = pixBg->convertToImage();
00132 pixBg->convertFromImage( img.smoothScale( width, height));
00133 }
00134 setBackgroundPixmap( *pixBg);
00135
00136 songInfo.setFocusPolicy( QWidget::NoFocus );
00137
00138
00139
00140
00141
00142
00143
00144
00145 slider.setFixedHeight( 20 );
00146 slider.setMinValue( 0 );
00147 slider.setMaxValue( 1 );
00148 slider.setFocusPolicy( QWidget::NoFocus );
00149
00150 slider.setBackgroundPixmap( *pixBg );
00151
00152 time.setFocusPolicy( QWidget::NoFocus );
00153 time.setAlignment( Qt::AlignCenter );
00154 time.setFrame(FALSE);
00155 changeTextColor( &time );
00156
00157 resizeEvent( NULL );
00158
00159 connect( &slider, SIGNAL( sliderPressed() ), this, SLOT( sliderPressed() ) );
00160 connect( &slider, SIGNAL( sliderReleased() ), this, SLOT( sliderReleased() ) );
00161
00162 connect( mediaPlayerState, SIGNAL( lengthChanged(long) ), this, SLOT( setLength(long) ) );
00163 connect( mediaPlayerState, SIGNAL( viewChanged(char) ), this, SLOT( setView(char) ) );
00164 connect( mediaPlayerState, SIGNAL( loopingToggled(bool) ), this, SLOT( setLooping(bool) ) );
00165
00166 connect( mediaPlayerState, SIGNAL( playingToggled(bool) ), this, SLOT( setPlaying(bool) ) );
00167
00168
00169 setLength( mediaPlayerState->length() );
00170 setPosition( mediaPlayerState->position() );
00171 setLooping( mediaPlayerState->fullscreen() );
00172
00173 setPlaying( mediaPlayerState->playing() );
00174 this->setFocus();
00175 if(this->x() < 0 || this->y() < 0)
00176 this->move(0,0);
00177 }
00178
00179
00180 AudioWidget::~AudioWidget() {
00181
00182
00183 for ( int i = 0; i < 10; i++ ) {
00184 if(buttonPixUp[i]) delete buttonPixUp[i];
00185 if(buttonPixDown[i]) delete buttonPixDown[i];
00186 }
00187 if(pixBg) delete pixBg;
00188 if(imgUp) delete imgUp;
00189 if(imgDn) delete imgDn;
00190 if(imgButtonMask) delete imgButtonMask;
00191 for ( int i = 0; i < 10; i++ ) {
00192 if(masks[i]) delete masks[i];
00193 }
00194 }
00195
00196
00197 QPixmap *combineImageWithBackground( QImage img, QPixmap bg, QPoint offset ) {
00198 QPixmap pix( img.width(), img.height() );
00199 QPainter p( &pix );
00200 p.drawTiledPixmap( pix.rect(), bg, offset );
00201 p.drawImage( 0, 0, img );
00202 return new QPixmap( pix );
00203 }
00204
00205
00206 QPixmap *maskPixToMask( QPixmap pix, QBitmap mask )
00207 {
00208 QPixmap *pixmap = new QPixmap( pix );
00209 pixmap->setMask( mask );
00210 return pixmap;
00211 }
00212
00213
00214
00215 void AudioWidget::resizeEvent( QResizeEvent * ) {
00216 int h = height();
00217 int w = width();
00218
00219 songInfo.setGeometry( QRect( 2, 10, w - 4, 20 ) );
00220 slider.setFixedWidth( w - 110 );
00221 slider.setGeometry( QRect( 15, h - 30, w - 90, 20 ) );
00222 slider.setBackgroundOrigin( QWidget::ParentOrigin );
00223 time.setGeometry( QRect( w - 85, h - 30, 70, 20 ) );
00224
00225 xoff = ( w - imgUp->width() ) / 2;
00226 yoff = (( h - imgUp->height() ) / 2) - 10;
00227 QPoint p( xoff, yoff );
00228
00229 QPixmap *pixUp = combineImageWithBackground( *imgUp, *pixBg, p );
00230 QPixmap *pixDn = combineImageWithBackground( *imgDn, *pixBg, p );
00231
00232 for ( int i = 0; i < 10; i++ ) {
00233 if ( !masks[i]->isNull() ) {
00234 delete buttonPixUp[i];
00235 delete buttonPixDown[i];
00236 buttonPixUp[i] = maskPixToMask( *pixUp, *masks[i] );
00237 buttonPixDown[i] = maskPixToMask( *pixDn, *masks[i] );
00238 }
00239 }
00240
00241 delete pixUp;
00242 delete pixDn;
00243 }
00244
00245
00246 static bool audioSliderBeingMoved = FALSE;
00247
00248 void AudioWidget::sliderPressed() {
00249 audioSliderBeingMoved = TRUE;
00250 }
00251
00252
00253 void AudioWidget::sliderReleased() {
00254 audioSliderBeingMoved = FALSE;
00255 if ( slider.width() == 0 )
00256 return;
00257 long val = long((double)slider.value() * mediaPlayerState->length() / slider.width());
00258 mediaPlayerState->setPosition( val );
00259 }
00260
00261
00262 void AudioWidget::setPosition( long i ) {
00263
00264 long length = mediaPlayerState->length();
00265 updateSlider( i, length );
00266 }
00267
00268
00269 void AudioWidget::setLength( long max ) {
00270 updateSlider( mediaPlayerState->position(), max );
00271 }
00272
00273
00274 void AudioWidget::setView( char view ) {
00275
00276 if (mediaPlayerState->isStreaming) {
00277 if( !slider.isHidden()) slider.hide();
00278 disconnect( mediaPlayerState, SIGNAL( positionChanged(long) ),this, SLOT( setPosition(long) ) );
00279 disconnect( mediaPlayerState, SIGNAL( positionUpdated(long) ),this, SLOT( setPosition(long) ) );
00280 } else {
00281
00282
00283 slider.show();
00284 connect( mediaPlayerState, SIGNAL( positionChanged(long) ),this, SLOT( setPosition(long) ) );
00285 connect( mediaPlayerState, SIGNAL( positionUpdated(long) ),this, SLOT( setPosition(long) ) );
00286 }
00287
00288 if ( view == 'a' ) {
00289 startTimer( 150 );
00290
00291 QPEApplication::showWidget( this );
00292 } else {
00293 killTimers();
00294 hide();
00295 }
00296
00297 }
00298
00299
00300 static QString timeAsString( long length ) {
00301 length /= 44100;
00302 int minutes = length / 60;
00303 int seconds = length % 60;
00304 return QString("%1:%2%3").arg( minutes ).arg( seconds / 10 ).arg( seconds % 10 );
00305 }
00306
00307 void AudioWidget::updateSlider( long i, long max ) {
00308 this->setFocus();
00309 time.setText( timeAsString( i ) + " / " + timeAsString( max ) );
00310
00311 if ( max == 0 )
00312 return;
00313
00314
00315 int width = slider.width();
00316 int val = int((double)i * width / max);
00317 if ( !audioSliderBeingMoved ) {
00318 if ( slider.value() != val )
00319 slider.setValue( val );
00320 if ( slider.maxValue() != width )
00321 slider.setMaxValue( width );
00322 }
00323 }
00324
00325
00326 void AudioWidget::setToggleButton( int i, bool down ) {
00327 if ( down != audioButtons[i].isDown )
00328 toggleButton( i );
00329 }
00330
00331
00332 void AudioWidget::toggleButton( int i ) {
00333 audioButtons[i].isDown = !audioButtons[i].isDown;
00334 QPainter p(this);
00335 paintButton ( &p, i );
00336 }
00337
00338
00339 void AudioWidget::paintButton( QPainter *p, int i ) {
00340 if ( audioButtons[i].isDown )
00341 p->drawPixmap( xoff, yoff, *buttonPixDown[i] );
00342 else
00343 p->drawPixmap( xoff, yoff, *buttonPixUp[i] );
00344 }
00345
00346
00347 void AudioWidget::timerEvent( QTimerEvent * ) {
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 }
00363
00364
00365 void AudioWidget::mouseMoveEvent( QMouseEvent *event ) {
00366 for ( int i = 0; i < numButtons; i++ ) {
00367 if ( event->state() == QMouseEvent::LeftButton ) {
00368
00369
00370 int x = event->pos().x() - xoff;
00371 int y = event->pos().y() - yoff;
00372
00373 bool isOnButton = ( x > 0 && y > 0 && x < imgButtonMask->width()
00374 && y < imgButtonMask->height() && imgButtonMask->pixelIndex( x, y ) == i + 1 );
00375
00376
00377
00378
00379 if ( isOnButton && !audioButtons[i].isHeld ) {
00380 audioButtons[i].isHeld = TRUE;
00381 toggleButton(i);
00382 switch (i) {
00383 case AudioVolumeUp:
00384
00385 emit moreClicked();
00386 return;
00387 case AudioVolumeDown:
00388
00389 emit lessClicked();
00390 return;
00391 case AudioForward:
00392 emit forwardClicked();
00393 return;
00394 case AudioBack:
00395 emit backClicked();
00396 return;
00397 }
00398 } else if ( !isOnButton && audioButtons[i].isHeld ) {
00399 audioButtons[i].isHeld = FALSE;
00400 toggleButton(i);
00401 }
00402 } else {
00403 if ( audioButtons[i].isHeld ) {
00404 audioButtons[i].isHeld = FALSE;
00405 if ( !audioButtons[i].isToggle )
00406 setToggleButton( i, FALSE );
00407 switch (i) {
00408 case AudioPlay:
00409 if( mediaPlayerState->isPaused ) {
00410 mediaPlayerState->setPaused( FALSE );
00411 return;
00412 } else if( !mediaPlayerState->isPaused ) {
00413 mediaPlayerState->setPaused( TRUE );
00414 return;
00415 }
00416
00417 case AudioStop: mediaPlayerState->setPlaying(FALSE); return;
00418
00419 case AudioNext: mediaPlayerState->setNext(); return;
00420 case AudioPrevious: mediaPlayerState->setPrev(); return;
00421 case AudioLoop: mediaPlayerState->setLooping(audioButtons[i].isDown); return;
00422 case AudioVolumeUp: emit moreReleased(); return;
00423 case AudioVolumeDown: emit lessReleased(); return;
00424 case AudioPlayList: mediaPlayerState->setList(); return;
00425 }
00426 }
00427 }
00428 }
00429 }
00430
00431
00432
00433 void AudioWidget::mousePressEvent( QMouseEvent *event ) {
00434 mouseMoveEvent( event );
00435 }
00436
00437
00438 void AudioWidget::mouseReleaseEvent( QMouseEvent *event ) {
00439 mouseMoveEvent( event );
00440 }
00441
00442
00443 void AudioWidget::showEvent( QShowEvent* ) {
00444 QMouseEvent event( QEvent::MouseMove, QPoint( 0, 0 ), 0, 0 );
00445 mouseMoveEvent( &event );
00446 }
00447
00448
00449 void AudioWidget::closeEvent( QCloseEvent* ) {
00450 mediaPlayerState->setList();
00451 }
00452
00453
00454 void AudioWidget::paintEvent( QPaintEvent * pe) {
00455 if ( !pe->erased() ) {
00456
00457 QPixmap pix( pe->rect().size() );
00458 QPainter p( &pix );
00459 p.translate( -pe->rect().topLeft().x(), -pe->rect().topLeft().y() );
00460 p.drawTiledPixmap( pe->rect(), *pixBg, pe->rect().topLeft() );
00461 for ( int i = 0; i < numButtons; i++ )
00462 paintButton( &p, i );
00463 QPainter p2( this );
00464 p2.drawPixmap( pe->rect().topLeft(), pix );
00465 } else {
00466 QPainter p( this );
00467 for ( int i = 0; i < numButtons; i++ )
00468 paintButton( &p, i );
00469 }
00470 }
00471
00472 void AudioWidget::keyReleaseEvent( QKeyEvent *e)
00473 {
00474 switch ( e->key() ) {
00476 case Key_Home:
00477 break;
00478 case Key_F9:
00479 hide();
00480
00481 break;
00482 case Key_F10:
00483 break;
00484 case Key_F11:
00485 break;
00486 case Key_F12:
00487 break;
00488 case Key_F13:
00489 break;
00490 case Key_Space: {
00491
00492 if(mediaPlayerState->playing()) {
00493
00494 mediaPlayerState->setPlaying(FALSE);
00495
00496 } else {
00497
00498 mediaPlayerState->setPlaying(TRUE);
00499
00500 }
00501 }
00502 break;
00503 case Key_Down:
00504
00505 emit lessClicked();
00506 emit lessReleased();
00507
00508 break;
00509 case Key_Up:
00510
00511 emit moreClicked();
00512 emit moreReleased();
00513
00514 break;
00515 case Key_Right:
00516
00517 mediaPlayerState->setNext();
00518
00519 break;
00520 case Key_Left:
00521
00522 mediaPlayerState->setPrev();
00523
00524 break;
00525 case Key_Escape:
00526 break;
00527
00528 };
00529 }