📄 controlwidgetbase.cpp
字号:
/************************************************************************ Copyright (C) 2000-2005 Trolltech AS. All rights reserved.**** This file is part of the Qtopia Environment.** ** 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.** ** A copy of the GNU GPL license version 2 is included in this package as ** LICENSE.GPL.**** This program is distributed in the hope that it will be useful, but** WITHOUT ANY WARRANTY; without even the implied warranty of** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ** See the GNU General Public License for more details.**** In addition, as a special exception Trolltech gives permission to link** the code of this program with Qtopia applications copyrighted, developed** and distributed by Trolltech under the terms of the Qtopia Personal Use** License Agreement. You must comply with the GNU General Public License** in all respects for all of the code used other than the applications** licensed under the Qtopia Personal Use License Agreement. If you modify** this file, you may extend this exception to your version of the file,** but you are not obligated to do so. If you do not wish to do so, delete** this exception statement from your version.** ** See http://www.trolltech.com/gpl/ for GPL licensing information.**** Contact info@trolltech.com if any conditions of this licensing are** not clear to you.************************************************************************/#include "imageutil.h"#include "mediaplayerstate.h"#include "controlwidgetbase.h"#include "audiodevice.h"#include <qtopia/config.h>#include <qtopia/mediaplayerplugininterface.h>#include <qtopia/resource.h>#include <qtopia/contextbar.h>#include <qapplication.h>#include <qbitmap.h>#include <qbutton.h>#include <qfile.h>#include <qfontmetrics.h>#include <qframe.h>#include <qlineedit.h>#include <qpainter.h>#include <qpixmap.h>#include <qtimer.h>#include <qwidget.h>#include <stdlib.h>#include <stdio.h>/*! \class ControlWidgetBase controlwidgetbase.h \brief This class is specific to the mediaplayer apps. It is currently private to those apps, and its API, and therefore binary compatibilty may change in later versions. It is the base class used to make the skinned audio and video views.*/ControlWidgetBase::ControlWidgetBase( QWidget* parent, const QString &skinPath, const QString &type, const char* name ) : QWidget(parent, name), buttonCount(0), slider(Qt::Horizontal, this), time(this), sliderBeingMoved(false), volumeTimeout(this), drawVolume(false){ setCaption( tr("Media Player") );// setMouseTracking( TRUE ); slider.setFixedHeight( 20 ); slider.setMinValue( 0 ); slider.setMaxValue( 1 ); slider.setFocusPolicy( QWidget::NoFocus ); time.setFocusPolicy( QWidget::NoFocus ); changeTextColor( &time ); skinW = 0; skinH = 0; skinScaleW = 0; skinScaleH = 0; skin = ""; skinFile = skinPath; skinType = type; imagesLoaded = FALSE; imagesScaled = FALSE; hadFirstResize = FALSE; resized = FALSE; canPaint = FALSE; actualScaleW = 0; actualScaleH = 0; connect( &slider, SIGNAL( sliderPressed() ), this, SLOT( sliderPressed() ) ); connect( &slider, SIGNAL( sliderReleased() ), this, SLOT( sliderReleased() ) ); connect( mediaPlayerState, SIGNAL( skinChanged(const QString&) ), this, SLOT( setSkin(const QString&) ) ); connect( mediaPlayerState, SIGNAL( lengthChanged(long) ), this, SLOT( setLength(long) ) ); connect( mediaPlayerState, SIGNAL( positionChanged(long) ),this, SLOT( setPosition(long) ) ); connect( mediaPlayerState, SIGNAL( positionUpdated(long) ),this, SLOT( setPosition(long) ) ); connect( mediaPlayerState, SIGNAL( seekableToggled(bool) ),this, SLOT( setSeekable(bool) ) ); //connect( mediaPlayerState, SIGNAL( viewChanged(View) ), this, SLOT( setView(View) ) ); connect( mediaPlayerState, SIGNAL( loopingToggled(bool) ), this, SLOT( setLooping(bool) ) ); connect( mediaPlayerState, SIGNAL( pausedToggled(bool) ), this, SLOT( setPaused(bool) ) ); connect( mediaPlayerState, SIGNAL( playingToggled(bool) ), this, SLOT( setPlaying(bool) ) ); connect( mediaPlayerState, SIGNAL( fullscreenToggled(bool) ), this, SLOT( setFullscreen(bool) ) ); connect( this, SIGNAL( moreClicked() ), mediaPlayerState, SIGNAL( increaseVolume() ) ); connect( this, SIGNAL( lessClicked() ), mediaPlayerState, SIGNAL( decreaseVolume() ) ); connect( this, SIGNAL( moreReleased() ), mediaPlayerState, SIGNAL( endIncreaseVolume() ) ); connect( this, SIGNAL( lessReleased() ), mediaPlayerState, SIGNAL( endDecreaseVolume() ) ); connect( this, SIGNAL( forwardClicked() ), mediaPlayerState, SIGNAL( scanForward() ) ); connect( this, SIGNAL( backwardClicked() ), mediaPlayerState, SIGNAL( scanBackward() ) ); connect( this, SIGNAL( forwardReleased() ), mediaPlayerState, SIGNAL( endScanForward() ) ); connect( this, SIGNAL( backwardReleased() ), mediaPlayerState, SIGNAL( endScanBackward() ) ); connect( &volumeTimeout, SIGNAL(timeout()), this, SLOT(hideVolumeOverlay()) ); setFocusPolicy( QWidget::StrongFocus );}ControlWidgetBase::~ControlWidgetBase(){}void ControlWidgetBase::setSkin( const QString& newskin ){ if ( skin == newskin ) return; qDebug("set %s skin", skinType.latin1() ); // Don't load and scale images yet. // Do this a bit at a time and as needed on demand mediaButtonImg[0].loaded = FALSE; mediaButtonImg[0].scaled = FALSE; mediaButtonImg[1].loaded = FALSE; mediaButtonImg[1].scaled = FALSE; for (int button = 0; button < MaxButtonTypes; button++) { mediaButtonMask[button].loaded = FALSE; mediaButtonMask[button].scaled = FALSE; } background.loaded = FALSE; imagesLoaded = FALSE; skin = newskin; // setSkin can be called from selecting a skin in the menus. It looks bad // to load the images etc while the menu is up so we delay the loading in a timer if ( resized || imagesScaled ) // If we have had a resize event we know what size to scale to and can // load and also scale silently in the background until we get a paintEvent QTimer::singleShot( 100, this, SLOT( scaleImages() ) ); else QTimer::singleShot( 0, this, SLOT( loadImages() ) );}void ControlWidgetBase::scaleImages(){ resizeObjects( skinW, skinH, skinScaleW, skinScaleH ); // Also set up the masks in the background if we can for ( int i = 0; i < buttonCount; i++ ) getButtonMask( i );}void ControlWidgetBase::loadImages(){ if ( imagesLoaded ) return; //qDebug("load %s images", skinType.latin1() ); QString skinPath = "mediaplayer/skins/" + skin + "/"; // Using findPixmap is a bit of an abuse Config cfg(Resource::findPixmap(skinPath+"config"), Config::File); cfg.setGroup("Skin"); if ( !background.loaded ) { background.scaledPix = Resource::loadPixmap( skinPath+cfg.readEntry("background", "background") ); bgNeedsScaling = FALSE; if ( background.scaledPix.isNull() ) background.scaledPix = Resource::loadPixmap( skinPath+cfg.readEntry("background_tiled", "background_tiled") ); if ( background.scaledPix.isNull() ) { background.unscaledImg = Resource::loadImage( skinPath+cfg.readEntry("background_scaled", "background_scaled") ); bgNeedsScaling = TRUE; } background.loaded = TRUE; } if ( !mediaButtonImg[0].loaded ) { QString filename = skinType+"_up"; mediaButtonImg[0].unscaledImg = Resource::loadImage( skinPath+cfg.readEntry(filename, filename) ); int xOff = cfg.readNumEntry(filename+"_x",0); int yOff = cfg.readNumEntry(filename+"_y",0); mediaButtonImg[0].offset = QPoint(xOff, yOff); mediaButtonImg[0].loaded = TRUE; } if ( !mediaButtonImg[1].loaded ) { QString filename = skinType+"_down"; mediaButtonImg[1].unscaledImg = Resource::loadImage( skinPath+cfg.readEntry(filename, filename) ); int xOff = cfg.readNumEntry(filename+"_x",0); int yOff = cfg.readNumEntry(filename+"_y",0); mediaButtonImg[1].offset = QPoint(xOff, yOff); mediaButtonImg[1].loaded = TRUE; } for ( int button = 0; button < buttonCount; button++ ) { if ( !mediaButtonMask[button].loaded ) { QString filename = skinType + "_mask_" + buttons[button].skinImage; // No tr int maskXOff = cfg.readNumEntry(filename+"_x",0); int maskYOff = cfg.readNumEntry(filename+"_y",0); filename = skinPath+cfg.readEntry(filename,filename); QString file = Resource::findPixmap( filename ); if ( ( buttons[button].hasImage = !file.isNull() ) ) { mediaButtonMask[button].unscaledImg = QImage( file ).convertDepth( 1 ); mediaButtonMask[button].offset = QPoint(maskXOff, maskYOff); mediaButtonMask[button].loaded = TRUE; } } } imagesLoaded = TRUE; //qDebug("loaded %s images", skinType.latin1() ); }void ControlWidgetBase::resetButtons(){ emit moreReleased(); emit lessReleased(); emit forwardReleased(); emit backwardReleased(); // Reset these buttons to unclicked for ( int i = 0; i < buttonCount; i++ ) { switch ( buttons[i].buttonType ) { case VolumeUpButton: case VolumeDownButton: case ForwardButton: case BackwardButton: buttons[i].isDown = FALSE; buttons[i].isHeld = FALSE; default: break; } }}void ControlWidgetBase::keyPressEvent( QKeyEvent *e ){ // Ignore all auto repeats if ( e->isAutoRepeat() ) return; switch( e->key() ) { case Key_Left: setToggleButton(BackwardButton,true); emit backwardClicked(); return; case Key_Right: setToggleButton(ForwardButton,true); emit forwardClicked(); return; case Key_Up: setToggleButton(VolumeUpButton,true); emit moreClicked(); return; case Key_Down: setToggleButton(VolumeDownButton,true); emit lessClicked(); return;#ifdef QTOPIA_PHONE case Key_Select:#endif case Key_Enter: case Key_Space: mediaPlayerState->setPaused( !mediaPlayerState->paused() ); return;#ifdef QTOPIA_PHONE case Key_No: case Key_Back:#endif case Key_Escape: mediaPlayerState->closeView(); return; default: break; }}void ControlWidgetBase::keyReleaseEvent( QKeyEvent *e ){ // Ignore all auto repeats if ( e->isAutoRepeat() ) return; switch( e->key() ) { case Key_Left: setToggleButton(BackwardButton,false); emit backwardReleased(); break; case Key_Right: setToggleButton(ForwardButton,false); emit forwardReleased(); break; case Key_Up: setToggleButton(VolumeUpButton,false); emit moreReleased(); return; case Key_Down: setToggleButton(VolumeDownButton,false); emit lessReleased(); return; default: break; }}void ControlWidgetBase::resizeEvent( QResizeEvent * ){ resized = TRUE; virtualResize();}static void paintIcon( QPainter& p, const char *icon, int x, int y, int size ){ QIconSet playIcon = Resource::loadIconSet(icon); QPixmap playPix = playIcon.pixmap(QIconSet::Large, QIconSet::Normal); QImage playImg = playPix.convertToImage(); playImg = playImg.smoothScale(size, size); p.drawImage(x, y, playImg);}void ControlWidgetBase::paintEvent( QPaintEvent *pe ){ if ( !resized ) { virtualResize(); resized = TRUE; } virtualPaint( pe ); if ( mediaButtonImg[0].scaledPix.isNull() ) { QPainter p(this); p.setPen( QPen(Qt::black, 1) ); int radius = QMIN(skinScaleW, skinScaleH) & ~2; p.drawEllipse( xoff, yoff, radius, radius ); p.drawEllipse( xoff + radius/4, yoff + radius/4, radius/2, radius/2 ); int iconSize = radius * 10 / 48; // divide by approximately sqrt(2) int centX = xoff + radius/2 - iconSize/2; int centY = yoff + radius/2 - iconSize/2; int space = radius*3/8; paintIcon(p, "fastback", centX - space, centY, iconSize); paintIcon(p, "play", centX, centY, iconSize); paintIcon(p, "fastforward", centX + space, centY, iconSize); paintIcon(p, "volume", centX, centY - space, iconSize); paintIcon(p, "volume", centX, centY + space, iconSize); } drawOverlays(); // Set up the masks for ( int i = 0; i < buttonCount; i++ ) getButtonMask( i );}static bool getPoint(Config &cfg, QString name, QPoint &pnt, int w, int h){ int x = cfg.readNumEntry(name+"_x",0x666666); int y = cfg.readNumEntry(name+"_y",0x666666); if (x < 0) x = QMAX(w + x, 0); if (y < 0) y = QMAX(h + y, 0); if (x != 0x666666 && y != 0x666666) { pnt = QPoint(x, y); return true; } return false;}static bool getRect(Config &cfg, QString name, QRect &rect, int w, int h){ QPoint tl = rect.topLeft(); QPoint br = rect.bottomRight(); if ( getPoint(cfg, name+"_tl", tl, w, h) && getPoint(cfg, name+"_br", br, w, h) ) { rect = QRect(tl, br); return true; } return false;}bool ControlWidgetBase::videoGeometry(QRect &geometry){ QString skinPath = "mediaplayer/skins/" + skin + "/"; Config cfg(Resource::findPixmap(skinPath+"config"), Config::File); cfg.setGroup("Skin"); return getRect(cfg, skinType+"_output", geometry, width(), height());}void ControlWidgetBase::resizeObjects( int w, int h, int scaleW, int scaleH, int cornerWidgetWidth ){ //qDebug("scale %s images -> %i %i %i %i", skinType.latin1(), w, h, scaleW, scaleH ); loadImages(); if ( !w || !h || !scaleW || !scaleH ) return; if ( bgNeedsScaling && !background.unscaledImg.isNull() ) background.scaledPix = background.unscaledImg.smoothScale( w, h ); if ( !background.scaledPix.isNull() ) { setBackgroundPixmap( background.scaledPix ); slider.setBackgroundOrigin( QWidget::ParentOrigin ); slider.setBackgroundPixmap( background.scaledPix ); } QString skinPath = "mediaplayer/skins/" + skin + "/"; Config cfg(Resource::findPixmap(skinPath+"config"), Config::File); cfg.setGroup("Skin"); int buttonsW, buttonsH; if ( !mediaButtonImg[0].unscaledImg.isNull() ) { buttonsW = mediaButtonImg[0].unscaledImg.width(); buttonsH = mediaButtonImg[0].unscaledImg.height(); } else { if ( skinType == "video" ) scaleW = scaleH = 1; buttonsW = buttonsH = 1; } scaleSize( scaleW, scaleH, buttonsW, buttonsH, ScaleMin ); // Save parameters used skinW = w; skinH = h; skinScaleW = scaleW; skinScaleH = scaleH; int border = w / 50; QFontMetrics fm( qApp->font() ); int timeWidth = fm.width( " 00:00 / 00:00 " ); int timeHeight = 20; // fm.height(); xoff = ( w - scaleW ) / 2; // Center buttons horizontally yoff = h - scaleH - timeHeight - 4*border; // Position buttons above slider and the time lineedit QRect skinButtonGeometry(xoff, yoff, scaleW, scaleH); getRect(cfg, skinType+"_button", skinButtonGeometry, w, h); xoff = skinButtonGeometry.x(); yoff = skinButtonGeometry.y(); scaleW = skinButtonGeometry.width(); scaleH = skinButtonGeometry.height(); scaleSize( scaleW, scaleH, buttonsW, buttonsH, ScaleMin ); actualScaleW = scaleW; actualScaleH = scaleH; imgButtonMask = QImage( scaleW, scaleH, 8, 255 ); imgButtonMask.fill( 0 ); int y1 = h - timeHeight - 2 * border; int x2 = w - timeWidth - border - cornerWidgetWidth; QRect sliderGeometry( border, y1, x2 - 2*border, timeHeight ); QRect timeGeometry( x2, y1, timeWidth, timeHeight ); getRect(cfg, skinType+"_slider", sliderGeometry, w, h); getRect(cfg, skinType+"_time", timeGeometry, w, h); slider.setGeometry(sliderGeometry); time.setGeometry(timeGeometry); // Force these to update mediaButtonImg[0].scaled = FALSE; mediaButtonImg[1].scaled = FALSE; for (int button = 0; button < buttonCount; button++) mediaButtonMask[button].scaled = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -