|
|
|
/***************************************************************************
|
|
|
|
playerwidget.cpp - description
|
|
|
|
-------------------
|
|
|
|
begin : Mit Nov 20 2002
|
|
|
|
copyright : (C) 2002 by Mark Kretschmann
|
|
|
|
email : 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 <tqaccel.h> //our quit shortcut in the ctor
|
|
|
|
#include <tqevent.h> //various events
|
|
|
|
#include <tqfont.h>
|
|
|
|
#include <tqhbox.h>
|
|
|
|
#include <tqlabel.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqpixmap.h>
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
#include <tqtooltip.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()
|
|
|
|
|
|
|
|
#include <kimageeffect.h>
|
|
|
|
|
|
|
|
//simple function for fetching amarok images
|
|
|
|
namespace Amarok
|
|
|
|
{
|
|
|
|
//TODO remove these, they suck, do a generic getImage
|
|
|
|
|
|
|
|
TQPixmap getPNG( const TQString &filename )
|
|
|
|
{
|
|
|
|
TQString file = !filename.endsWith( ".png", false ) ? "amarok/images/%1.png" : "amarok/images/%1";
|
|
|
|
|
|
|
|
TQPixmap pix;
|
|
|
|
TQImage img( locate( "data", file.tqarg( filename ) ), "PNG" );
|
|
|
|
if (TQPaintDevice::x11AppDepth() == 32) pix.convertFromImage(KImageEffect::convertToPremultipliedAlpha( img ));
|
|
|
|
else pix.convertFromImage( img );
|
|
|
|
return pix;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQPixmap getJPG( const TQString &filename )
|
|
|
|
{
|
|
|
|
TQString file = !filename.endsWith( ".jpg", false ) ? "amarok/images/%1.jpg" : "amarok/images/%1";
|
|
|
|
|
|
|
|
TQPixmap pix;
|
|
|
|
TQImage img( locate( "data", TQString( "amarok/images/%1.jpg" ).tqarg( filename ) ), "JPEG" );
|
|
|
|
if (TQPaintDevice::x11AppDepth() == 32) pix.convertFromImage(KImageEffect::convertToPremultipliedAlpha( img ));
|
|
|
|
else pix.convertFromImage( img );
|
|
|
|
return pix;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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 TQRect &r, TQWidget *parent, const char *name = 0, TQt::WFlags f = 0 )
|
|
|
|
{
|
|
|
|
W *w = new W( parent, name, f );
|
|
|
|
w->setGeometry( r );
|
|
|
|
return w;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
PlayerWidget::PlayerWidget( TQWidget *parent, const char *name, bool enablePlaylist )
|
|
|
|
: TQWidget( parent, name, TQt::WType_TopLevel )
|
|
|
|
, EngineObserver( EngineController::instance() )
|
|
|
|
, m_minimalView( false )
|
|
|
|
, m_pAnimTimer( new TQTimer( 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 tqgeometry 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() != TQPoint(-1,-1) )
|
|
|
|
move( AmarokConfig::playerPos() );
|
|
|
|
|
|
|
|
setModifiedPalette();
|
|
|
|
setFixedSize( 311, 140 );
|
|
|
|
setCaption( "Amarok" );
|
|
|
|
setAcceptDrops( true );
|
|
|
|
|
|
|
|
//another quit shortcut because the other window has all the accels
|
|
|
|
TQAccel *accel = new TQAccel( this );
|
|
|
|
accel->insertItem( CTRL + Key_Q );
|
|
|
|
connect( accel, TQT_SIGNAL( activated( int ) ), kapp, TQT_SLOT( quit() ) );
|
|
|
|
|
|
|
|
TQFont font;
|
|
|
|
font.setBold( true );
|
|
|
|
font.setPixelSize( 10 );
|
|
|
|
setFont( font );
|
|
|
|
|
|
|
|
{ //<NavButtons>
|
|
|
|
//NOTE we use a tqlayout for the buttons so resizing will be possible
|
|
|
|
m_pFrameButtons = createWidget<TQHBox>( TQRect(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( TQSizePolicy::Maximum, TQSizePolicy::Preferred ); // too big!
|
|
|
|
switchView->setFocusPolicy( TQ_NoFocus );
|
|
|
|
connect( switchView, TQT_SIGNAL( clicked() ), TQT_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, TQT_SIGNAL(sliderReleased( int )), ec, TQT_SLOT(seek( int )) );
|
|
|
|
connect( m_pSlider, TQT_SIGNAL(valueChanged( int )), TQT_SLOT(timeDisplay( int )) );
|
|
|
|
connect( m_pVolSlider, TQT_SIGNAL(sliderMoved( int )), ec, TQT_SLOT(setVolume( int )) );
|
|
|
|
connect( m_pVolSlider, TQT_SIGNAL(sliderReleased( int )), ec, TQT_SLOT(setVolume( int )) );
|
|
|
|
} //<Sliders>
|
|
|
|
|
|
|
|
{ //<Scroller>
|
|
|
|
font.setPixelSize( 11 );
|
|
|
|
const int fontHeight = TQFontMetrics( font ).height(); //the real height is more like 13px
|
|
|
|
|
|
|
|
m_pScrollFrame = createWidget<TQFrame>( TQRect(6,18, 285,fontHeight), this );
|
|
|
|
m_pScrollFrame->setFont( font );
|
|
|
|
{ //</Scroller>
|
|
|
|
|
|
|
|
} //<TimeLabel>
|
|
|
|
font.setPixelSize( 18 );
|
|
|
|
|
|
|
|
m_pTimeLabel = createWidget<TQLabel>( TQRect(16,36, 9*12+2,18), this, 0, TQt::WNoAutoErase );
|
|
|
|
m_pTimeLabel->setFont( font );
|
|
|
|
|
|
|
|
m_timeBuffer.resize( m_pTimeLabel->size() );
|
|
|
|
m_timeBuffer.fill( backgroundColor() );
|
|
|
|
} //<TimeLabel>
|
|
|
|
|
|
|
|
|
|
|
|
m_pButtonEq = new IconButton( TQT_TQWIDGET(this), "eq", TQT_TQOBJECT(this), TQT_SLOT(slotShowEqualizer( bool )) );
|
|
|
|
m_pButtonEq->setGeometry( 34,85, 28,13 );
|
|
|
|
//TODO set isOn()
|
|
|
|
|
|
|
|
m_pPlaylistButton = new IconButton( this, "pl", TQT_SIGNAL(playlistToggled( bool )) );
|
|
|
|
m_pPlaylistButton->setGeometry( 5,85, 28,13 );
|
|
|
|
m_pPlaylistButton->setOn( parent->isShown() || enablePlaylist );
|
|
|
|
|
|
|
|
|
|
|
|
m_pDescription = createWidget<TQLabel>( TQRect(4,6, 250,10), this );
|
|
|
|
m_pTimeSign = createWidget<TQLabel>( TQRect(6,40, 10,10), this, 0, TQt::WRepaintNoErase );
|
|
|
|
m_pVolSign = createWidget<TQLabel>( TQRect(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, TQT_SIGNAL( timeout() ), TQT_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 TQStringList &list )
|
|
|
|
{
|
|
|
|
TQString text;
|
|
|
|
TQStringList list2( list );
|
|
|
|
TQStringList::Iterator end( list2.end() );
|
|
|
|
for( TQStringList::Iterator it = list2.begin(); it != end; )
|
|
|
|
{
|
|
|
|
if( !(*it).isEmpty() )
|
|
|
|
{
|
|
|
|
text.append( *it );
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
else it = list2.remove( it );
|
|
|
|
}
|
|
|
|
|
|
|
|
//FIXME empty TQString would crash due to NULL Pixmaps
|
|
|
|
if( text.isEmpty() ) text = i18n( "Please report this message to amarok@kde.org, thanks!" );
|
|
|
|
|
|
|
|
TQFont font( m_pScrollFrame->font() );
|
|
|
|
TQFontMetrics 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() );
|
|
|
|
|
|
|
|
TQPainter p( &m_scrollTextPixmap );
|
|
|
|
p.setPen( foregroundColor() );
|
|
|
|
p.setFont( font );
|
|
|
|
uint x = 0;
|
|
|
|
|
|
|
|
for( TQStringList::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;
|
|
|
|
|
|
|
|
TQPixmap* const buffer = &m_scrollBuffer;
|
|
|
|
TQPixmap* 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, TQt::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 );
|
|
|
|
m_pSlider->setValue( 0 );
|
|
|
|
m_pSlider->setMinValue( 0 );
|
|
|
|
m_pSlider->setMaxValue( 0 );
|
|
|
|
m_pSlider->newBundle( MetaBundle() ); // Set an empty bundle for no moodbar
|
|
|
|
m_pTimeLabel->hide();
|
|
|
|
m_pTimeSign->hide();
|
|
|
|
m_rateString = TQString();
|
|
|
|
m_pSlider->setEnabled( false );
|
|
|
|
setScroll( i18n( "Welcome to Amarok" ) );
|
|
|
|
update();
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Engine::Playing:
|
|
|
|
if( !m_minimalView )
|
|
|
|
{
|
|
|
|
m_pTimeLabel->show();
|
|
|
|
m_pTimeSign->show();
|
|
|
|
}
|
|
|
|
m_pButtonPlay->setOn( true );
|
|
|
|
m_pButtonPause->setOn( false );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Engine::Paused:
|
|
|
|
m_pButtonPause->setOn( true );
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Engine::Idle: //don't really want to do anything when idle
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PlayerWidget::engineVolumeChanged( int percent )
|
|
|
|
{
|
|
|
|
m_pVolSlider->setValue( percent );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PlayerWidget::engineNewMetaData( const MetaBundle &bundle, bool )
|
|
|
|
{
|
|
|
|
m_currentURL == bundle.url().path();
|
|
|
|
|
|
|
|
m_pSlider->setMinValue( 0 ); // Important. minValue could have been changed by bogus maxValues
|
|
|
|
m_pSlider->setMaxValue( bundle.length() * 1000 );
|
|
|
|
m_pSlider->setEnabled( bundle.length() > 0 );
|
|
|
|
m_pSlider->newBundle( bundle );
|
|
|
|
|
|
|
|
m_rateString = bundle.prettyBitrate();
|
|
|
|
TQString Hz = bundle.prettySampleRate( true );
|
|
|
|
if( !Hz.isEmpty() )
|
|
|
|
{
|
|
|
|
if( m_rateString.isEmpty() )
|
|
|
|
m_rateString = Hz;
|
|
|
|
else
|
|
|
|
m_rateString = i18n("%1 kBit - %2").tqarg( m_rateString, Hz );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQStringList list( bundle.prettyTitle() );
|
|
|
|
list << bundle.album();
|
|
|
|
if( bundle.length() ) list << bundle.prettyLength();
|
|
|
|
setScroll( list );
|
|
|
|
|
|
|
|
update(); //we need to update rateString
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PlayerWidget::engineTrackPositionChanged( long position, bool /*userSeek*/ )
|
|
|
|
{
|
|
|
|
m_pSlider->setValue( position );
|
|
|
|
|
|
|
|
if( !m_pSlider->isEnabled() ) timeDisplay( position );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PlayerWidget::engineTrackLengthChanged( long length )
|
|
|
|
{
|
|
|
|
m_pSlider->setMaxValue( length * 1000 );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PlayerWidget::timeDisplay( int ms )
|
|
|
|
{
|
|
|
|
int seconds = ms / 1000;
|
|
|
|
const int songLength = EngineController::instance()->bundle().length();
|
|
|
|
const bool showRemaining = AmarokConfig::leftTimeDisplayRemaining() && songLength > 0;
|
|
|
|
|
|
|
|
if( showRemaining ) seconds = songLength - seconds;
|
|
|
|
|
|
|
|
m_timeBuffer.fill( backgroundColor() );
|
|
|
|
TQPainter p( &m_timeBuffer );
|
|
|
|
p.setPen( foregroundColor() );
|
|
|
|
p.setFont( m_pTimeLabel->font() );
|
|
|
|
p.drawText( 0, 16, MetaBundle::prettyTime( seconds ) ); //FIXME remove padding, instead move()!
|
|
|
|
bitBlt( m_pTimeLabel, 0, 0, &m_timeBuffer );
|
|
|
|
|
|
|
|
m_pTimeSign->setPixmap( showRemaining ? m_minusPixmap : m_plusPixmap );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static inline TQColor comodulate( int hue, TQColor target )
|
|
|
|
{
|
|
|
|
///this function is only used by determineAmarokColors()
|
|
|
|
int ignore, s, v;
|
|
|
|
target.getHsv( &ignore, &s, &v );
|
|
|
|
return TQColor( hue, s, v, TQColor::Hsv );
|
|
|
|
}
|
|
|
|
|
|
|
|
void PlayerWidget::determineAmarokColors() //static
|
|
|
|
{
|
|
|
|
int hue, s, v;
|
|
|
|
|
|
|
|
(!AmarokConfig::schemeKDE()
|
|
|
|
? AmarokConfig::playlistWindowBgColor()
|
|
|
|
: KGlobalSettings::highlightColor()
|
|
|
|
).getHsv( &hue, &s, &v );
|
|
|
|
|
|
|
|
using namespace Amarok::ColorScheme;
|
|
|
|
|
|
|
|
Text = TQt::white;
|
|
|
|
Background = comodulate( hue, 0x002090 );
|
|
|
|
Foreground = comodulate( hue, 0x80A0FF );
|
|
|
|
|
|
|
|
//ensure the base colour does not conflict with the window decoration colour
|
|
|
|
//however generally it is nice to leave the other colours with the highlight hue
|
|
|
|
//because the scheme is then "complimentary"
|
|
|
|
//TODO schemes that have totally different active/inactive decoration colours need to be catered for too!
|
|
|
|
if ( AmarokConfig::schemeKDE() ) {
|
|
|
|
int h;
|
|
|
|
KGlobalSettings::activeTitleColor().getHsv( &h, &s, &v );
|
|
|
|
if( TQABS( hue - h ) > 120 )
|
|
|
|
hue = h;
|
|
|
|
}
|
|
|
|
|
|
|
|
Base = comodulate( hue, Amarok::blue );
|
|
|
|
}
|
|
|
|
|
|
|
|
void PlayerWidget::setModifiedPalette()
|
|
|
|
{
|
|
|
|
TQPalette p = TQApplication::palette();
|
|
|
|
TQColorGroup cg = p.active();
|
|
|
|
cg.setColor( TQColorGroup::Background, Amarok::ColorScheme::Base );
|
|
|
|
cg.setColor( TQColorGroup::Foreground, Amarok::ColorScheme::Text );
|
|
|
|
setPalette( TQPalette(cg, p.disabled(), cg) );
|
|
|
|
}
|
|
|
|
|
|
|
|
void PlayerWidget::applySettings()
|
|
|
|
{
|
|
|
|
//NOTE DON'T use unsetFont(), we use custom font sizes (for now)
|
|
|
|
TQFont phont = font();
|
|
|
|
phont.setFamily( AmarokConfig::useCustomFonts()
|
|
|
|
? AmarokConfig::playerWidgetFont().family()
|
|
|
|
: TQApplication::font().family() );
|
|
|
|
setFont( phont );
|
|
|
|
|
|
|
|
setModifiedPalette();
|
|
|
|
|
|
|
|
//update the scroller
|
|
|
|
switch( EngineController::engine()->state() ) {
|
|
|
|
case Engine::Empty:
|
|
|
|
m_scrollTextPixmap.fill( Amarok::ColorScheme::Base );
|
|
|
|
update();
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
engineNewMetaData( EngineController::instance()->bundle(), false );
|
|
|
|
}
|
|
|
|
|
|
|
|
if(m_pAnalyzer)
|
|
|
|
setMinimalView(m_minimalView);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PlayerWidget::setMinimalView( bool enable )
|
|
|
|
{
|
|
|
|
m_pAnalyzer->setHidden( enable );
|
|
|
|
m_pTimeLabel->setHidden( enable );
|
|
|
|
m_pTimeSign->setHidden( enable );
|
|
|
|
m_pDescription->setHidden( enable );
|
|
|
|
m_pButtonEq->setHidden( enable );
|
|
|
|
m_pPlaylistButton->setHidden( enable );
|
|
|
|
m_pVolSlider->setHidden( enable );
|
|
|
|
|
|
|
|
if( enable )
|
|
|
|
{
|
|
|
|
uint space = 2;
|
|
|
|
m_pScrollFrame->setGeometry ( 6,space, m_pScrollFrame->width(), m_pScrollFrame->height() );
|
|
|
|
m_pSlider->setGeometry ( 4,space + m_pScrollFrame->height(), 303, 12 );
|
|
|
|
m_pFrameButtons->setGeometry( 0,space + m_pScrollFrame->height() + m_pSlider->height(), 311,22 );
|
|
|
|
uint height = m_pFrameButtons->height() + m_pScrollFrame->height() + m_pSlider->height() + space;
|
|
|
|
setFixedSize( 311, height );
|
|
|
|
AmarokConfig::setPlayerWindowMinimalView( true );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_pScrollFrame->setGeometry( 6,18, m_pScrollFrame->width(),m_pScrollFrame->height() );
|
|
|
|
m_pSlider->setGeometry( 4,103, 303,12 );
|
|
|
|
m_pFrameButtons->setGeometry(0,118, 311,22);
|
|
|
|
setFixedSize( 311, 140 );
|
|
|
|
AmarokConfig::setPlayerWindowMinimalView( false );
|
|
|
|
}
|
|
|
|
|
|
|
|
m_minimalView = enable;
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// EVENTS -----------------------------------------------------------------
|
|
|
|
|
|
|
|
static bool dontChangeButtonState = false; //FIXME I hate this hack
|
|
|
|
|
|
|
|
bool PlayerWidget::event( TQEvent *e )
|
|
|
|
{
|
|
|
|
switch( e->type() )
|
|
|
|
{
|
|
|
|
case TQEvent::Wheel:
|
|
|
|
case TQEvent::DragEnter:
|
|
|
|
case TQEvent::Drop:
|
|
|
|
case TQEvent::Close:
|
|
|
|
|
|
|
|
Amarok::genericEventHandler( this, e );
|
|
|
|
return true; //we handled it
|
|
|
|
|
|
|
|
case TQEvent::ApplicationPaletteChange:
|
|
|
|
|
|
|
|
if( AmarokConfig::schemeKDE() )
|
|
|
|
{
|
|
|
|
determineAmarokColors();
|
|
|
|
applySettings();
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case 6/*TQEvent::KeyPress*/:
|
|
|
|
if (TQT_TQKEYEVENT(e)->key() == TQt::Key_D/* && (m_pAnalyzer->inherits(TQGLWIDGET_OBJECT_NAME_STRING)*/)
|
|
|
|
{
|
|
|
|
if( m_pAnalyzer->parent() )
|
|
|
|
{
|
|
|
|
m_pAnalyzer->reparent( 0, TQPoint(50,50), true );
|
|
|
|
m_pAnalyzer->setCaption( kapp->makeStdCaption( i18n("Analyzer") ) );
|
|
|
|
m_pAnalyzer->installEventFilter( this );
|
|
|
|
m_pAnalyzer->setPaletteBackgroundColor( paletteBackgroundColor() );
|
|
|
|
TQToolTip::remove( m_pAnalyzer );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
createAnalyzer( 0 );
|
|
|
|
|
|
|
|
return true; //eat event
|
|
|
|
}
|
|
|
|
return false; //don't eat event
|
|
|
|
|
|
|
|
case TQEvent::Show:
|
|
|
|
|
|
|
|
m_pAnimTimer->start( ANIM_TIMER );
|
|
|
|
|
|
|
|
if( m_pPlaylistButton->isOn() )
|
|
|
|
{
|
|
|
|
//IMPORTANT! If the PlaylistButton is on then we MUST be shown
|
|
|
|
//we leave the PlaylistButton "on" to signify that we should restore it here
|
|
|
|
//we leave it on when we do a hidePlaylistWithPlayerWindow type action
|
|
|
|
|
|
|
|
//IMPORTANT - I beg of you! Please leave all this alone, it was hell to
|
|
|
|
//create! If you have an issue with the behaviour bring it up on the mailing
|
|
|
|
//list before you even think about committing. Thanks! (includes case Hide)
|
|
|
|
|
|
|
|
const WId id = parentWidget()->winId();
|
|
|
|
const uint desktop = KWin::windowInfo( winId() ).desktop();
|
|
|
|
const KWin::WindowInfo info = KWin::windowInfo( id );
|
|
|
|
|
|
|
|
//check the Playlist Window is on the correct desktop
|
|
|
|
if( !info.isOnDesktop( desktop ) ) KWin::setOnDesktop( id, desktop );
|
|
|
|
|
|
|
|
if( info.mappingState() == NET::Withdrawn )
|
|
|
|
{
|
|
|
|
//extern Atom qt_wm_state; //XAtom defined by TQt
|
|
|
|
|
|
|
|
//TODO prevent the active Window flicker from playlist to player window please!
|
|
|
|
//TODO look at code for TQWidget::show();
|
|
|
|
|
|
|
|
//XDeleteProperty( qt_xdisplay(), id, qt_wm_state );
|
|
|
|
|
|
|
|
//parentWidget()->show();
|
|
|
|
//if( !parentWidget()->isShown() ) XMapWindow( qt_xdisplay(), id );
|
|
|
|
// unsigned long data[2];
|
|
|
|
// data[0] = (unsigned long) NormalState;
|
|
|
|
// data[1] = (unsigned long) None;
|
|
|
|
//
|
|
|
|
// XChangeProperty( qt_xdisplay(), id, qt_wm_state, qt_wm_state, 32,
|
|
|
|
// PropModeReplace, (unsigned char *)data, 2);
|
|
|
|
//
|
|
|
|
// KWin::clearState( id, NET::Hidden );
|
|
|
|
//
|
|
|
|
// XMapWindow( qt_xdisplay(), id );
|
|
|
|
//
|
|
|
|
//KWin::deIconifyWindow( id, false );
|
|
|
|
parentWidget()->show();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if( info.isMinimized() )
|
|
|
|
{
|
|
|
|
//then the user will expect us to deiconify the Playlist Window
|
|
|
|
//the PlaylistButton would be off otherwise (honest!)
|
|
|
|
KWin::deIconifyWindow( id, false );
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
case TQEvent::Hide:
|
|
|
|
m_pAnimTimer->stop();
|
|
|
|
|
|
|
|
{
|
|
|
|
//this prevents the PlaylistButton being set to off (see the eventFilter)
|
|
|
|
//by leaving it on we ensure that we show the Playlist Window again when
|
|
|
|
//we are next shown (see Show event handler above)
|
|
|
|
if( parentWidget()->isShown() ) dontChangeButtonState = true;
|
|
|
|
|
|
|
|
if( e->spontaneous() ) //the window system caused the event
|
|
|
|
{
|
|
|
|
//if we have been iconified, iconify the Playlist Window too
|
|
|
|
//if we have been shaded, hide the PlaylistWindow
|
|
|
|
//if the user is on another desktop to Amarok, do nothing
|
|
|
|
|
|
|
|
const KWin::WindowInfo info = KWin::windowInfo( winId() );
|
|
|
|
|
|
|
|
if( info.isMinimized() ) KWin::iconifyWindow( parentWidget()->winId(), false );
|
|
|
|
else
|
|
|
|
//this may seem strange, but it is correct
|
|
|
|
//we have a handler in eventFilter for all other eventualities
|
|
|
|
dontChangeButtonState = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
//we caused Amarok to hide, so we should hide the Playlist Window
|
|
|
|
//NOTE we "override" closeEvents and thus they count as non-spontaneous
|
|
|
|
//hideEvents; which frankly is a huge relief!
|
|
|
|
parentWidget()->hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return TQWidget::event( e );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// bool
|
|
|
|
// PlayerWidget::x11Event( XEvent *e )
|
|
|
|
// {
|
|
|
|
// if( e->type == ConfigureNotify )
|
|
|
|
// {
|
|
|
|
// kdDebug() << "CirculateNotify\n";
|
|
|
|
// XRaiseWindow( x11Display(), playlistWindow()->winId() );
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// return false;
|
|
|
|
// }
|
|
|
|
|
|
|
|
bool
|
|
|
|
PlayerWidget::eventFilter( TQObject *o, TQEvent *e )
|
|
|
|
{
|
|
|
|
//NOTE we only monitor for parent() - which is the PlaylistWindow
|
|
|
|
|
|
|
|
if( TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_pAnalyzer) )
|
|
|
|
{
|
|
|
|
//delete analyzer, create same one back in Player Window
|
|
|
|
if( e->type() == TQEvent::Close )
|
|
|
|
{
|
|
|
|
createAnalyzer( 0 );
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch( e->type() )
|
|
|
|
{
|
|
|
|
case TQEvent::Close:
|
|
|
|
|
|
|
|
TQT_TQCLOSEEVENT(e)->accept(); //close the window!
|
|
|
|
return true; //don't let PlaylistWindow have the event - see PlaylistWindow::closeEvent()
|
|
|
|
|
|
|
|
case TQEvent::Hide:
|
|
|
|
|
|
|
|
if( dontChangeButtonState )
|
|
|
|
{
|
|
|
|
//we keep the PlaylistButton set to "on" - see event() for more details
|
|
|
|
//NOTE the Playlist Window will still be hidden
|
|
|
|
|
|
|
|
dontChangeButtonState = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if( e->spontaneous() )
|
|
|
|
{
|
|
|
|
//we want to avoid setting the button for most spontaneous events
|
|
|
|
//since they are not user driven, two are however:
|
|
|
|
|
|
|
|
KWin::WindowInfo info = KWin::windowInfo( parentWidget()->winId() );
|
|
|
|
|
|
|
|
if( !info.isMinimized() ) break;
|
|
|
|
}
|
|
|
|
|
|
|
|
//FALL THROUGH
|
|
|
|
|
|
|
|
case TQEvent::Show:
|
|
|
|
|
|
|
|
if( isShown() )
|
|
|
|
{
|
|
|
|
//only when shown means thaman:mkreiserfst using the global Show/Hide Playlist shortcut
|
|
|
|
//when in the tray doesn't effect the state of the PlaylistButton
|
|
|
|
//this is a good thing, but we have to set the state correctly when we are shown
|
|
|
|
|
|
|
|
m_pPlaylistButton->blockSignals( true );
|
|
|
|
m_pPlaylistButton->setOn( e->type() == TQEvent::Show );
|
|
|
|
m_pPlaylistButton->blockSignals( false );
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PlayerWidget::paintEvent( TQPaintEvent* )
|
|
|
|
{
|
|
|
|
//uses widget's font and foregroundColor() - see ctor
|
|
|
|
TQPainter p( this );
|
|
|
|
if( !m_minimalView )
|
|
|
|
p.drawText( 6, 68, m_rateString );
|
|
|
|
|
|
|
|
bitBlt( m_pScrollFrame, 0, 0, &m_scrollBuffer );
|
|
|
|
bitBlt( m_pTimeLabel, 0, 0, &m_timeBuffer );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PlayerWidget::contextMenuEvent( TQMouseEvent *e )
|
|
|
|
{
|
|
|
|
Amarok::Menu::instance()->exec( e->globalPos() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void PlayerWidget::mousePressEvent( TQMouseEvent *e )
|
|
|
|
{
|
|
|
|
if ( e->button() == Qt::RightButton )
|
|
|
|
{
|
|
|
|
//Amarok::Menu::instance()->exec( e->globalPos() );
|
|
|
|
}
|
|
|
|
else if ( m_pAnalyzer->tqgeometry().contains( e->pos() ) )
|
|
|
|
{
|
|
|
|
createAnalyzer( e->state() & TQt::ControlButton ? -1 : +1 );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TQRect
|
|
|
|
rect = m_pTimeLabel->tqgeometry();
|
|
|
|
rect |= m_pTimeSign->tqgeometry();
|
|
|
|
|
|
|
|
if ( rect.contains( e->pos() ) )
|
|
|
|
{
|
|
|
|
AmarokConfig::setLeftTimeDisplayRemaining( !AmarokConfig::leftTimeDisplayRemaining() );
|
|
|
|
timeDisplay( EngineController::engine()->position() );
|
|
|
|
}
|
|
|
|
else m_startDragPos = e->pos();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PlayerWidget::mouseMoveEvent( TQMouseEvent *e )
|
|
|
|
{
|
|
|
|
if( e->state() & Qt::LeftButton )
|
|
|
|
{
|
|
|
|
const int distance = (e->pos() - m_startDragPos).manhattanLength();
|
|
|
|
|
|
|
|
if( distance > TQApplication::startDragDistance() ) startDrag();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// SLOTS ---------------------------------------------------------------------
|
|
|
|
|
|
|
|
void PlayerWidget::createAnalyzer( int increment )
|
|
|
|
{
|
|
|
|
AmarokConfig::setCurrentAnalyzer( AmarokConfig::currentAnalyzer() + increment );
|
|
|
|
|
|
|
|
delete m_pAnalyzer;
|
|
|
|
|
|
|
|
m_pAnalyzer = Analyzer::Factory::createAnalyzer( this );
|
|
|
|
m_pAnalyzer->setGeometry( 120,40, 168,56 );
|
|
|
|
TQToolTip::add( m_pAnalyzer, i18n( "Click for more analyzers, press 'd' to detach." ) );
|
|
|
|
m_pAnalyzer->show();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void PlayerWidget::startDrag()
|
|
|
|
{
|
|
|
|
TQDragObject *d = new TQTextDrag( EngineController::instance()->bundle().prettyTitle(), this );
|
|
|
|
d->dragCopy();
|
|
|
|
// TQt will delete d for us.
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void PlayerWidget::slotShowEqualizer( bool show ) //SLOT
|
|
|
|
{
|
|
|
|
if( show )
|
|
|
|
{
|
|
|
|
m_pButtonEq->setOff();
|
|
|
|
|
|
|
|
if ( !EngineController::hasEngineProperty( "HasEqualizer" ) )
|
|
|
|
KMessageBox::sorry( 0, i18n( "Equalizer is not available with this engine." ) );
|
|
|
|
|
|
|
|
else
|
|
|
|
TQTimer::singleShot( 0, kapp, TQT_SLOT( slotConfigEqualizer() ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// CLASS NavButton
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include <kiconeffect.h>
|
|
|
|
#include <kimageeffect.h>
|
|
|
|
NavButton::NavButton( TQWidget *parent, const TQString &icon, KAction *action )
|
|
|
|
: TQToolButton( parent )
|
|
|
|
, m_glowIndex( 0 )
|
|
|
|
{
|
|
|
|
// Prevent flicker
|
|
|
|
setWFlags( TQt::WNoAutoErase );
|
|
|
|
|
|
|
|
TQPixmap pixmap( getPNG( "b_" + icon ) );
|
|
|
|
KIconEffect ie;
|
|
|
|
|
|
|
|
// Tint icon blueish for "off" state
|
|
|
|
m_pixmapOff = ie.apply( pixmap, KIconEffect::Colorize, 0.5, TQColor( 0x30, 0x10, 0xff ), false );
|
|
|
|
// Tint gray and make pseudo-transparent for "disabled" state
|
|
|
|
m_pixmapDisabled = ie.apply( pixmap, KIconEffect::ToGray, 0.7, TQColor(), true );
|
|
|
|
|
|
|
|
int r = 0x20, g = 0x10, b = 0xff;
|
|
|
|
float percentRed = 0.0;
|
|
|
|
TQPixmap temp;
|
|
|
|
// Precalculate pixmaps for "on" icon state
|
|
|
|
for ( int i = 0; i < NUMPIXMAPS; i++ ) {
|
|
|
|
TQImage img = pixmap.convertToImage();
|
|
|
|
temp = KImageEffect::channelIntensity( img, percentRed, KImageEffect::Red );
|
|
|
|
temp = ie.apply( temp, KIconEffect::Colorize, 1.0, TQColor( r, 0x10, 0x30 ), false );
|
|
|
|
temp = ie.apply( temp, KIconEffect::Colorize, 1.0, TQColor( r, g, b ), false );
|
|
|
|
|
|
|
|
// Create new pixmap on the heap and add pointer to list
|
|
|
|
m_glowPixmaps.append( temp );
|
|
|
|
|
|
|
|
percentRed = percentRed + 1.0 / NUMPIXMAPS;
|
|
|
|
r += 14;
|
|
|
|
g += 2;
|
|
|
|
b -= 0;
|
|
|
|
}
|
|
|
|
// And the the same reversed
|
|
|
|
for ( int i = NUMPIXMAPS - 1; i > 0; i-- )
|
|
|
|
{
|
|
|
|
TQPixmap temp = m_glowPixmaps[i];
|
|
|
|
m_glowPixmaps.append(temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is just for initialization
|
|
|
|
TQIconSet iconSet;
|
|
|
|
iconSet.setPixmap( pixmap, TQIconSet::Automatic, TQIconSet::Normal, TQIconSet::Off );
|
|
|
|
iconSet.setPixmap( pixmap, TQIconSet::Automatic, TQIconSet::Normal, TQIconSet::On );
|
|
|
|
iconSet.setPixmap( pixmap, TQIconSet::Automatic, TQIconSet::Disabled, TQIconSet::Off );
|
|
|
|
setIconSet( iconSet );
|
|
|
|
|
|
|
|
setFocusPolicy( TQ_NoFocus );
|
|
|
|
setEnabled( action->isEnabled() );
|
|
|
|
|
|
|
|
connect( action, TQT_SIGNAL( enabled( bool ) ), TQT_SLOT( setEnabled( bool ) ) );
|
|
|
|
connect( this, TQT_SIGNAL( clicked() ), action, TQT_SLOT( activate() ) );
|
|
|
|
startTimer( GLOW_INTERVAL );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void NavButton::timerEvent( TQTimerEvent* )
|
|
|
|
{
|
|
|
|
if ( isOn() ) {
|
|
|
|
m_glowIndex++;
|
|
|
|
m_glowIndex %= NUMPIXMAPS * 2 - 1;
|
|
|
|
|
|
|
|
// Repaint widget with new pixmap
|
|
|
|
update();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void NavButton::drawButtonLabel( TQPainter* p )
|
|
|
|
{
|
|
|
|
int x = width() / 2 - m_pixmapOff.width() / 2;
|
|
|
|
int y = height() / 2 - m_pixmapOff.height() / 2;
|
|
|
|
|
|
|
|
if ( !isEnabled() )
|
|
|
|
p->drawPixmap( x, y, m_pixmapDisabled );
|
|
|
|
else if ( isOn() )
|
|
|
|
p->drawPixmap( x + 2, y + 1, m_glowPixmaps[m_glowIndex] );
|
|
|
|
else
|
|
|
|
p->drawPixmap( x, y, m_pixmapOff );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// CLASS IconButton
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
IconButton::IconButton( TQWidget *parent, const TQString &icon, const char *signal )
|
|
|
|
: TQButton( parent )
|
|
|
|
, m_up( getPNG( icon + "_active2" ) ) //TODO rename files better (like the right way round for one!)
|
|
|
|
, m_down( getPNG( icon + "_inactive2" ) )
|
|
|
|
{
|
|
|
|
connect( this, TQT_SIGNAL(toggled( bool )), parent, signal );
|
|
|
|
|
|
|
|
setToggleButton( true );
|
|
|
|
setFocusPolicy( TQ_NoFocus ); //we have no way to show focus on these widgets currently
|
|
|
|
}
|
|
|
|
|
|
|
|
IconButton::IconButton( TQWidget *parent, const TQString &icon, TQObject* receiver, const char *slot )
|
|
|
|
: TQButton( parent )
|
|
|
|
, m_up( getPNG( icon + "_active2" ) ) //TODO rename files better (like the right way round for one!)
|
|
|
|
, m_down( getPNG( icon + "_inactive2" ) )
|
|
|
|
{
|
|
|
|
connect( this, TQT_SIGNAL(toggled( bool )), receiver, slot );
|
|
|
|
|
|
|
|
setToggleButton( true );
|
|
|
|
setFocusPolicy( TQ_NoFocus ); //we have no way to show focus on these widgets currently
|
|
|
|
}
|
|
|
|
|
|
|
|
void IconButton::drawButton( TQPainter *p )
|
|
|
|
{
|
|
|
|
p->drawPixmap( 0, 0, (isOn()||isDown()) ? m_down : m_up );
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "playerwindow.moc"
|