/* * * $Id: k3bjobprogressosd.cpp 619556 2007-01-03 17:38:12Z trueg $ * Copyright (C) 2005 Sebastian Trueg * * This file is part of the K3b project. * Copyright (C) 1998-2007 Sebastian Trueg * * 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. * See the file "COPYING" for the exact licensing terms. */ #include "k3bjobprogressosd.h" #include #include #include #include #include #include #include #include #include #include #include #include #include K3bJobProgressOSD::K3bJobProgressOSD( TQWidget* parent, const char* name ) : TQWidget( parent, name, WType_TopLevel | WNoAutoErase | WStyle_Customize | WX11BypassWM | WStyle_StaysOnTop ), m_dirty(true), m_progress(0), m_dragging(false), m_screen(0), m_position(s_outerMargin, s_outerMargin) { setFocusPolicy( TQ_NoFocus ); setBackgroundMode( NoBackground ); // dummy size resize( 20, 20 ); // make sure we are always visible KWin::setOnAllDesktops( winId(), true ); connect( k3bappcore->themeManager(), TQT_SIGNAL(themeChanged()), this, TQT_SLOT(refresh()) ); connect( kapp, TQT_SIGNAL(appearanceChanged()), this, TQT_SLOT(refresh()) ); } K3bJobProgressOSD::~K3bJobProgressOSD() { } void K3bJobProgressOSD::show() { // start with 0 progress setProgress(0); if( m_dirty ) renderOSD(); TQWidget::show(); } void K3bJobProgressOSD::setText( const TQString& text ) { if( m_text != text ) { m_text = text; refresh(); } } void K3bJobProgressOSD::setProgress( int p ) { if( m_progress != p ) { m_progress = p; refresh(); } } void K3bJobProgressOSD::setPosition( const TQPoint& p ) { m_position = p; reposition(); } void K3bJobProgressOSD::refresh() { if( isVisible() ) renderOSD(); else m_dirty = true; } void K3bJobProgressOSD::renderOSD() { // ---------------------------------------- // | Copying CD | // | K3B ========== 40% | // | | // ---------------------------------------- // calculate needed size if( K3bTheme* theme = k3bappcore->themeManager()->currentTheme() ) { TQPixmap icon = KGlobal::iconLoader()->loadIcon( "k3b", KIcon::NoGroup, 32 ); int margin = 10; int textWidth = fontMetrics().width( m_text ); // do not change the size every time the text changes, just in case we are too small TQSize newSize( TQMAX( TQMAX( 2*margin + icon.width() + margin + textWidth, 100 ), width() ), TQMAX( 2*margin + icon.height(), 2*margin + fontMetrics().height()*2 ) ); m_osdBuffer.resize( newSize ); TQPainter p( &m_osdBuffer ); p.setPen( theme->foregroundColor() ); // draw the background and the frame TQRect thisRect( 0, 0, newSize.width(), newSize.height() ); p.fillRect( thisRect, theme->backgroundColor() ); p.drawRect( thisRect ); // draw the k3b icon p.drawPixmap( margin, (newSize.height()-icon.height())/2, icon ); // draw the text TQSize textSize = fontMetrics().size( 0, m_text ); int textX = 2*margin + icon.width(); int textY = margin + fontMetrics().ascent(); p.drawText( textX, textY, m_text ); // draw the progress textY += fontMetrics().descent() + 4; TQRect progressRect( textX, textY, newSize.width()-textX-margin, newSize.height()-textY-margin ); p.drawRect( progressRect ); progressRect.setWidth( m_progress > 0 ? m_progress*progressRect.width()/100 : 0 ); p.fillRect( progressRect, theme->foregroundColor() ); // reposition the osd reposition( newSize ); m_dirty = false; update(); } } void K3bJobProgressOSD::setScreen( int screen ) { const int n = TQApplication::desktop()->numScreens(); m_screen = (screen >= n) ? n-1 : screen; reposition(); } void K3bJobProgressOSD::reposition( TQSize newSize ) { if( !newSize.isValid() ) newSize = size(); TQPoint newPos = m_position; const TQRect& screen = TQApplication::desktop()->screenGeometry( m_screen ); // now to properly resize if put into one of the corners we interpret the position // depending on the quadrant int midH = screen.width()/2; int midV = screen.height()/2; if( newPos.x() > midH ) newPos.rx() -= newSize.width(); if( newPos.y() > midV ) newPos.ry() -= newSize.height(); newPos = fixupPosition( newPos ); // correct for screen position newPos += screen.topLeft(); // ensure we are painted before we move if( isVisible() ) paintEvent( 0 ); // fancy X11 move+resize, reduces visual artifacts XMoveResizeWindow( x11Display(), winId(), newPos.x(), newPos.y(), newSize.width(), newSize.height() ); } void K3bJobProgressOSD::paintEvent( TQPaintEvent* ) { bitBlt( this, 0, 0, &m_osdBuffer ); } void K3bJobProgressOSD::mousePressEvent( TQMouseEvent* e ) { m_dragOffset = e->pos(); if( e->button() == Qt::LeftButton && !m_dragging ) { grabMouse( KCursor::sizeAllCursor() ); m_dragging = true; } else if( e->button() == Qt::RightButton ) { KPopupMenu m; if( m.insertItem( i18n("Hide OSD") ) == m.exec( e->globalPos() ) ) hide(); } } void K3bJobProgressOSD::mouseReleaseEvent( TQMouseEvent* ) { if( m_dragging ) { m_dragging = false; releaseMouse(); } } void K3bJobProgressOSD::mouseMoveEvent( TQMouseEvent* e ) { if( m_dragging && this == mouseGrabber() ) { // check if the osd has been dragged out of the current screen int currentScreen = TQApplication::desktop()->screenNumber( e->globalPos() ); if( currentScreen != -1 ) m_screen = currentScreen; const TQRect& screen = TQApplication::desktop()->screenGeometry( m_screen ); // make sure the position is valid m_position = fixupPosition( e->globalPos() - m_dragOffset - screen.topLeft() ); // move us to the new position move( m_position ); // fix the position int midH = screen.width()/2; int midV = screen.height()/2; if( m_position.x() + width() > midH ) m_position.rx() += width(); if( m_position.y() + height() > midV ) m_position.ry() += height(); } } TQPoint K3bJobProgressOSD::fixupPosition( const TQPoint& pp ) { TQPoint p(pp); const TQRect& screen = TQApplication::desktop()->screenGeometry( m_screen ); int maxY = screen.height() - height() - s_outerMargin; int maxX = screen.width() - width() - s_outerMargin; if( p.y() < s_outerMargin ) p.ry() = s_outerMargin; else if( p.y() > maxY ) p.ry() = maxY; if( p.x() < s_outerMargin ) p.rx() = s_outerMargin; else if( p.x() > maxX ) p.rx() = screen.width() - s_outerMargin - width(); p += screen.topLeft(); return p; } void K3bJobProgressOSD::readSettings( KConfigBase* c ) { KConfigGroup grp( c, "OSD Position" ); setPosition( grp.readPointEntry( "Position", 0 ) ); setScreen( grp.readNumEntry( "Screen", 0 ) ); } void K3bJobProgressOSD::saveSettings( KConfigBase* c ) { KConfigGroup grp( c, "OSD Position" ); grp.writeEntry( "Position", m_position ); grp.writeEntry( "Screen", m_screen ); } #include "k3bjobprogressosd.moc"