?? playerwindow.cpp
字號:
/*************************************************************************** playerwidget.cpp - description -------------------begin : Mit Nov 20 2002copyright : (C) 2002 by Mark Kretschmannemail : markey@web.de***************************************************************************//*************************************************************************** * * * 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. * * * ***************************************************************************/#include "actionclasses.h"#include "amarok.h"#include "amarokconfig.h"#include "analyzerbase.h"#include "debug.h"#include "enginecontroller.h"#include "metabundle.h" //setScroll()#include "playerwindow.h"#include "sliderwidget.h"#include "tracktooltip.h" //setScroll()#include <qaccel.h> //our quit shortcut in the ctor#include <qevent.h> //various events#include <qfont.h>#include <qhbox.h>#include <qlabel.h>#include <qpainter.h>#include <qpixmap.h>#include <qstringlist.h>#include <qtimer.h>#include <qtooltip.h> //analyzer tooltip#include <kapplication.h>#include <klocale.h>#include <kmessagebox.h>#include <kpushbutton.h>#include <kstandarddirs.h>#include <kurldrag.h>#include <kwin.h> //eventFilter()//simple function for fetching amarok imagesnamespace Amarok{ //TODO remove these, they suck, do a generic getImage QPixmap getPNG( const QString &filename ) { QString file = !filename.endsWith( ".png", false ) ? "amarok/images/%1.png" : "amarok/images/%1"; return QPixmap( locate( "data", file.arg( filename ) ), "PNG" ); } QPixmap getJPG( const QString &filename ) { QString file = !filename.endsWith( ".jpg", false ) ? "amarok/images/%1.jpg" : "amarok/images/%1"; return QPixmap( locate( "data", QString( "amarok/images/%1.jpg" ).arg( filename ) ), "JPEG" ); }}using Amarok::getPNG;//fairly pointless template which was designed to make the ctor clearer,//but probably achieves the opposite. Still, the code is neater..template<class W> static inline W*createWidget( const QRect &r, QWidget *parent, const char *name = 0, Qt::WFlags f = 0 ){ W *w = new W( parent, name, f ); w->setGeometry( r ); return w;}PlayerWidget::PlayerWidget( QWidget *parent, const char *name, bool enablePlaylist ) : QWidget( parent, name, Qt::WType_TopLevel ) , EngineObserver( EngineController::instance() ) , m_minimalView( false ) , m_pAnimTimer( new QTimer( this ) ) , m_scrollBuffer( 291, 16 ) , m_plusPixmap( getPNG( "time_plus" ) ) , m_minusPixmap( getPNG( "time_minus" ) ) , m_pAnalyzer( 0 ){ //the createWidget template function is used here //createWidget just creates a widget which has it's geometry set too // Sets caption and icon correctly (needed e.g. for GNOME) kapp->setTopWidget( this ); parent->installEventFilter( this ); //for hidePLaylistWithMainWindow mode //if this is the first time we have ever been run we let KWin place us if ( AmarokConfig::playerPos() != QPoint(-1,-1) ) move( AmarokConfig::playerPos() ); setModifiedPalette(); setFixedSize( 311, 140 ); setCaption( "Amarok" ); setAcceptDrops( true ); //another quit shortcut because the other window has all the accels QAccel *accel = new QAccel( this ); accel->insertItem( CTRL + Key_Q ); connect( accel, SIGNAL( activated( int ) ), kapp, SLOT( quit() ) ); QFont font; font.setBold( true ); font.setPixelSize( 10 ); setFont( font ); { //<NavButtons> //NOTE we use a layout for the buttons so resizing will be possible m_pFrameButtons = createWidget<QHBox>( QRect(0, 118, 311, 22), this ); KActionCollection *ac =Amarok::actionCollection(); //FIXME change the names of the icons to reflect kde names so we can fall back to them if necessary new NavButton( m_pFrameButtons, "prev", ac->action( "prev" ) ); m_pButtonPlay = new NavButton( m_pFrameButtons, "play", ac->action( "play" ) ); m_pButtonPause = new NavButton( m_pFrameButtons, "pause", ac->action( "pause" ) ); new NavButton( m_pFrameButtons, "stop", ac->action( "stop" ) ); new NavButton( m_pFrameButtons, "next", ac->action( "next" ) ); KPushButton *switchView = new KPushButton( KGuiItem( "", "mini_dock" ), m_pFrameButtons ); switchView->setSizePolicy( QSizePolicy::Maximum, QSizePolicy::Preferred ); // too big! switchView->setFocusPolicy( QWidget::NoFocus ); connect( switchView, SIGNAL( clicked() ), SLOT( toggleView() ) ); m_pButtonPlay->setToggleButton( true ); m_pButtonPause->setToggleButton( true ); } //</NavButtons> { //<Sliders> m_pSlider = new Amarok::PrettySlider( Qt::Horizontal, Amarok::PrettySlider::Pretty, this ); m_pVolSlider = new Amarok::PrettySlider( Qt::Vertical, Amarok::PrettySlider::Pretty, this, Amarok::VOLUME_MAX ); m_pSlider->setGeometry( 4,103, 303, 12 ); m_pVolSlider->setGeometry( 294,18, 12,79 ); m_pVolSlider->setValue( AmarokConfig::masterVolume() ); EngineController* const ec = EngineController::instance(); connect( m_pSlider, SIGNAL(sliderReleased( int )), ec, SLOT(seek( int )) ); connect( m_pSlider, SIGNAL(valueChanged( int )), SLOT(timeDisplay( int )) ); connect( m_pVolSlider, SIGNAL(sliderMoved( int )), ec, SLOT(setVolume( int )) ); connect( m_pVolSlider, SIGNAL(sliderReleased( int )), ec, SLOT(setVolume( int )) ); } //<Sliders> { //<Scroller> font.setPixelSize( 11 ); const int fontHeight = QFontMetrics( font ).height(); //the real height is more like 13px m_pScrollFrame = createWidget<QFrame>( QRect(6,18, 285,fontHeight), this ); m_pScrollFrame->setFont( font ); { //</Scroller> } //<TimeLabel> font.setPixelSize( 18 ); m_pTimeLabel = createWidget<QLabel>( QRect(16,36, 9*12+2,18), this, 0, Qt::WNoAutoErase ); m_pTimeLabel->setFont( font ); m_timeBuffer.resize( m_pTimeLabel->size() ); m_timeBuffer.fill( backgroundColor() ); } //<TimeLabel> m_pButtonEq = new IconButton( this, "eq", this, SLOT(slotShowEqualizer( bool )) ); m_pButtonEq->setGeometry( 34,85, 28,13 ); //TODO set isOn() m_pPlaylistButton = new IconButton( this, "pl", SIGNAL(playlistToggled( bool )) ); m_pPlaylistButton->setGeometry( 5,85, 28,13 ); m_pPlaylistButton->setOn( parent->isShown() || enablePlaylist ); m_pDescription = createWidget<QLabel>( QRect(4,6, 250,10), this ); m_pTimeSign = createWidget<QLabel>( QRect(6,40, 10,10), this, 0, Qt::WRepaintNoErase ); m_pVolSign = createWidget<QLabel>( QRect(295,7, 9,8), this ); m_pDescription->setText( i18n( "Artist-Title|Album|Length" ) ); m_pVolSign ->setPixmap( getPNG( "vol_speaker" ) ); //do before we set the widget's state applySettings(); //set interface to correct state engineStateChanged( EngineController::engine()->state() ); createAnalyzer( 0 ); //so we get circulation events to x11Event() //XSelectInput( x11Display(), winId(), StructureNotifyMask ); //Yagami mode! //KWin::setState( winId(), NET::KeepBelow | NET::SkipTaskbar | NET::SkipPager ); //KWin::setType( winId(), NET::Override ); //KWin::setOnAllDesktops( winId(), true ); connect( m_pAnimTimer, SIGNAL( timeout() ), SLOT( drawScroll() ) ); TrackToolTip::instance()->addToWidget( m_pScrollFrame );}PlayerWidget::~PlayerWidget(){ AmarokConfig::setPlayerPos( pos() ); AmarokConfig::setPlaylistWindowEnabled( m_pPlaylistButton->isOn() ); TrackToolTip::instance()->removeFromWidget( m_pScrollFrame );}// METHODS ----------------------------------------------------------------void PlayerWidget::setScroll( const QStringList &list ){ QString text; QStringList list2( list ); QStringList::Iterator end( list2.end() ); for( QStringList::Iterator it = list2.begin(); it != end; ) { if( !(*it).isEmpty() ) { text.append( *it ); ++it; } else it = list2.remove( it ); } //FIXME empty QString would crash due to NULL Pixmaps if( text.isEmpty() ) text = i18n( "Please report this message to amarok@kde.org, thanks!" ); QFont font( m_pScrollFrame->font() ); QFontMetrics fm( font ); const uint separatorWidth = 21; const uint baseline = font.pixelSize(); //the font actually extends below its pixelHeight const uint separatorYPos = baseline - fm.boundingRect( "x" ).height() + 1; m_scrollTextPixmap.resize( fm.width( text ) + list2.count() * separatorWidth, m_pScrollFrame->height() ); m_scrollTextPixmap.fill( backgroundColor() ); QPainter p( &m_scrollTextPixmap ); p.setPen( foregroundColor() ); p.setFont( font ); uint x = 0; for( QStringList::ConstIterator it = list2.constBegin(); it != list2.constEnd(); ++it ) { p.drawText( x, baseline, *it ); x += fm.width( *it ); p.fillRect( x + 8, separatorYPos, 4, 4, Amarok::ColorScheme::Foreground ); x += separatorWidth; } drawScroll();}void PlayerWidget::drawScroll(){ static uint phase = 0; QPixmap* const buffer = &m_scrollBuffer; QPixmap* const scroll = &m_scrollTextPixmap; const uint topMargin = 0; //moved margins into widget placement const uint leftMargin = 0; //as this makes it easier to fiddle const uint w = m_scrollTextPixmap.width(); const uint h = m_scrollTextPixmap.height(); phase += SCROLL_RATE; if( phase >= w ) phase = 0; int subs = 0; int dx = leftMargin; uint phase2 = phase; while( dx < m_pScrollFrame->width() ) { subs = -m_pScrollFrame->width() + topMargin; subs += dx + ( w - phase2 ); if( subs < 0 ) subs = 0; bitBlt( buffer, dx, topMargin, scroll, phase2, 0, w - phase2 - subs, h, Qt::CopyROP ); dx += w - phase2; phase2 += w - phase2; if( phase2 >= w ) phase2 = 0; } bitBlt( m_pScrollFrame, 0, 0, buffer );}void PlayerWidget::engineStateChanged( Engine::State state, Engine::State /*oldState*/ ){ DEBUG_BLOCK switch( state ) { case Engine::Empty: m_pButtonPlay->setOn( false ); m_pButtonPause->setOn( false );
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -