Пример #1
0
void PlaylistItem::drawRating( QPainter *p )
{
    int gray = 0;
    if( this == listView()->m_hoveredRating || ( isSelected() && listView()->m_selCount > 1 &&
        listView()->m_hoveredRating && listView()->m_hoveredRating->isSelected() ) )
    {
        const int pos = listView()->viewportToContents( listView()->viewport()->mapFromGlobal( QCursor::pos() ) ).x();
        gray = ratingAtPoint( pos );
    }

    drawRating( p, ( rating() + 1 ) / 2, gray / 2, rating() % 2 );
}
Пример #2
0
void RatingComboBoxDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option,
                                   const QModelIndex& index) const
{
    QVariant value  = index.data(Qt::DisplayRole);
    bool selectable = index.flags() & Qt::ItemIsSelectable;

    if (value.type() == QVariant::Int)
    {
        painter->save();
        drawBackground(painter, option, index);
        drawDisplay(painter, option, option.rect, QString());

        // our custom painting
        drawRating(painter, option.rect, value.toInt(), selectable);

        drawFocus(painter, option, option.rect);
        painter->restore();
    }
    else
    {
        return QItemDelegate::paint(painter, option, index);
    }
}
Пример #3
0
void PlaylistItem::paintCell( QPainter *painter, const QColorGroup &cg, int column, int width, int align )
{
    //TODO add spacing on either side of items
    //p->translate( 2, 0 ); width -= 3;

    // Don't try to draw if width or height is 0, as this crashes Qt
    if( !painter || !listView() || width <= 0 || height() == 0 )
        return;

    static const QImage currentTrackLeft  = locate( "data", "amarok/images/currenttrack_bar_left.png" );
    static const QImage currentTrackMid   = locate( "data", "amarok/images/currenttrack_bar_mid.png" );
    static const QImage currentTrackRight = locate( "data", "amarok/images/currenttrack_bar_right.png" );

    if( column == Mood  &&  !moodbar().dataExists() )
      moodbar().load();  // Only has an effect the first time
    // The moodbar column can have text in it, like "Calculating".
    // moodbarType is 0 if column != Mood, 1 if we're displaying
    // a moodbar, and 2 if we're displaying text
    const int moodbarType =
        column != Mood ? 0 : moodbar().state() == Moodbar::Loaded ? 1 : 2;

    const QString colText = text( column );
    const bool isCurrent = this == listView()->currentTrack();

    QPixmap buf( width, height() );
    QPainter p( &buf, true );

    if( isCurrent )
    {
        static paintCacheItem paintCache[NUM_COLUMNS];

        // Convert intensity to string, so we can use it as a key
        const QString colorKey = QString::number( glowIntensity );

        const bool cacheValid =
            paintCache[column].width == width &&
            paintCache[column].height == height() &&
            paintCache[column].text == colText &&
            paintCache[column].font == painter->font() &&
            paintCache[column].color == glowBase &&
            paintCache[column].selected == isSelected() &&
            !s_pixmapChanged;

            // If any parameter changed, we must regenerate all pixmaps
            if ( !cacheValid )
            {
                for( int i = 0; i < NUM_COLUMNS; ++i)
                    paintCache[i].map.clear();
                s_pixmapChanged = false;
            }

            // Determine if we need to repaint the pixmap, or paint from cache
            if ( paintCache[column].map.find( colorKey ) == paintCache[column].map.end() )
            {
                // Update painting cache
                paintCache[column].width = width;
                paintCache[column].height = height();
                paintCache[column].text = colText;
                paintCache[column].font = painter->font();
                paintCache[column].color = glowBase;
                paintCache[column].selected = isSelected();

                QColor bg;
                if( isSelected() )
                    bg = listView()->colorGroup().highlight();
                else
                    bg = isAlternate() ? listView()->alternateBackground() :
                                        listView()->viewport()->backgroundColor();

                buf.fill( bg );

                // Draw column divider line
                p.setPen( listView()->viewport()->colorGroup().mid() );
                p.drawLine( width - 1, 0, width - 1, height() - 1 );

                // Here we draw the background bar graphics for the current track:
                //
                // Illustration of design, L = Left, M = Middle, R = Right:
                // <LMMMMMMMMMMMMMMMR>

                int leftOffset  = 0;
                int rightOffset = 0;
                int margin      = listView()->itemMargin();

                const float  colorize  = 0.8;
                const double intensity = 1.0 - glowIntensity * 0.021;

                // Left part
                if( column == listView()->m_firstColumn ) {
                    QImage tmpImage = currentTrackLeft.smoothScale( 1, height(), QImage::ScaleMax );
                    KIconEffect::colorize( tmpImage, glowBase, colorize );
                    imageTransparency( tmpImage, intensity );
                    p.drawImage( 0, 0, tmpImage, 0, 0, tmpImage.width() - 1 ); //HACK
                    leftOffset = tmpImage.width() - 1; //HACK Subtracting 1, to work around the black line bug
                    margin += 6;
                }

                // Right part
                else
                if( column == Playlist::instance()->mapToLogicalColumn( Playlist::instance()->numVisibleColumns() - 1 ) )
                {
                    QImage tmpImage = currentTrackRight.smoothScale( 1, height(), QImage::ScaleMax );
                    KIconEffect::colorize( tmpImage, glowBase, colorize );
                    imageTransparency( tmpImage, intensity );
                    p.drawImage( width - tmpImage.width(), 0, tmpImage );
                    rightOffset = tmpImage.width();
                    margin += 6;
                }

                // Middle part
                // Here we scale the one pixel wide middel image to stretch to the full column width.
                QImage tmpImage = currentTrackMid.copy();
                KIconEffect::colorize( tmpImage, glowBase, colorize );
                imageTransparency( tmpImage, intensity );
                tmpImage = tmpImage.smoothScale( width - leftOffset - rightOffset, height() );
                p.drawImage( leftOffset, 0, tmpImage );


                // Draw the pixmap, if present
                int leftMargin = margin;
                if ( pixmap( column ) ) {
                    p.drawPixmap( leftMargin, height() / 2 - pixmap( column )->height() / 2, *pixmap( column ) );
                    leftMargin += pixmap( column )->width() + 2;
                }

                if( align != Qt::AlignCenter )
                align |= Qt::AlignVCenter;

                if( column != Rating  &&
                    moodbarType != 1 )
                {
                    // Draw the text
                    static QFont font;
                    static int minbearing = 1337 + 666;
                    if( minbearing == 2003 || font != painter->font() )
                    {
                        font = painter->font();
                        minbearing = painter->fontMetrics().minLeftBearing()
                                    + painter->fontMetrics().minRightBearing();
                    }
                    const bool italic = font.italic();
                    int state = EngineController::engine()->state();
                    if( state == Engine::Playing || state == Engine::Paused )
                        font.setItalic( !italic );
                    p.setFont( font );
                    p.setPen( cg.highlightedText() );
//                  paint.setPen( glowText );
                    const int _width = width - leftMargin - margin + minbearing - 1; // -1 seems to be necessary
                    const QString _text = KStringHandler::rPixelSqueeze( colText, painter->fontMetrics(), _width );
                    p.drawText( leftMargin, 0, _width, height(), align, _text );
                    font.setItalic( italic );
                    p.setFont( font );
                }

                paintCache[column].map[colorKey] = buf;
            }
            else
                p.drawPixmap( 0, 0, paintCache[column].map[colorKey] );
            if( column == Rating )
                drawRating( &p );
            if( moodbarType == 1 )
                drawMood( &p, width, height() );
        }
    else
    {
        const QColorGroup _cg = ( !exists() || !isEnabled() )
                                ? listView()->palette().disabled()
                                : listView()->palette().active();

        QColor bg = isSelected()  ? _cg.highlight()
                    : isAlternate() ? listView()->alternateBackground()
                    : listView()->viewport()->backgroundColor();
        #if KDE_IS_VERSION( 3, 3, 91 )
        if( listView()->shadeSortColumn() && !isSelected() && listView()->columnSorted() == column )
        {
            /* from klistview.cpp
                Copyright (C) 2000 Reginald Stadlbauer <*****@*****.**>
                Copyright (C) 2000,2003 Charles Samuels <*****@*****.**>
                Copyright (C) 2000 Peter Putzer */
            if ( bg == Qt::black )
                bg = QColor(55, 55, 55);  // dark gray
            else
            {
                int h,s,v;
                bg.hsv(&h, &s, &v);
                if ( v > 175 )
                    bg = bg.dark(104);
                else
                    bg = bg.light(120);
            }
        }
        #endif

        const QColor textc = isSelected() ? _cg.highlightedText() : _cg.text();

        buf.fill( bg );

        // Draw column divider line
        if( !isSelected() )
        {
            p.setPen( listView()->viewport()->colorGroup().mid() );
            p.drawLine( width - 1, 0, width - 1, height() - 1 );
        }

        // Draw the pixmap, if present
        int margin = listView()->itemMargin(), leftMargin = margin;
        if ( pixmap( column ) ) {
            p.drawPixmap( leftMargin, height() / 2 - pixmap( column )->height() / 2, *pixmap( column ) );
            leftMargin += pixmap( column )->width();
        }

        if( align != Qt::AlignCenter )
            align |= Qt::AlignVCenter;

        if( column == Rating )
            drawRating( &p );
        else if( moodbarType == 1 )
            drawMood( &p, width, height() );
        else
        {
            // Draw the text
            static QFont font;
            static int minbearing = 1337 + 666; //can be 0 or negative, 2003 is less likely
            if( minbearing == 2003 || font != painter->font() )
            {
                font = painter->font(); //getting your bearings can be expensive, so we cache them
                minbearing = painter->fontMetrics().minLeftBearing()
                                + painter->fontMetrics().minRightBearing();
            }
            p.setFont( font );
            p.setPen( ( m_isNew && isEnabled() && !isSelected() ) ? AmarokConfig::newPlaylistItemsColor() : textc );
            
            const int _width = width - leftMargin - margin + minbearing - 1; // -1 seems to be necessary
            const QString _text = KStringHandler::rPixelSqueeze( colText, painter->fontMetrics(), _width );
            p.drawText( leftMargin, 0, _width, height(), align, _text );
        }
    }
    /// Track action symbols
    const int  queue       = listView()->m_nextTracks.findRef( this ) + 1;
    const bool stop        = ( this == listView()->m_stopAfterTrack );
    const bool repeat      = Amarok::repeatTrack() && isCurrent;

    const uint num = ( queue ? 1 : 0 ) + ( stop ? 1 : 0 ) + ( repeat ? 1 : 0 );

    static const QPixmap pixstop   = Amarok::getPNG(  "currenttrack_stop_small"  ),
                         pixrepeat = Amarok::getPNG( "currenttrack_repeat_small" );

    //figure out if we are in the actual physical first column
    if( column == listView()->m_firstColumn && num )
    {
        //margin, height
        const uint m = 2, h = height() - m;

        const QString str = QString::number( queue );

        const uint qw = painter->fontMetrics().width( str ), sw = pixstop.width(),  rw = pixrepeat.width(),
                   qh = painter->fontMetrics().height(),     sh = pixstop.height(), rh = pixrepeat.height();

        //maxwidth
        const uint mw = kMax( qw, kMax( rw, sw ) );

        //width of first & second column of pixmaps
        const uint w1 = ( num == 3 ) ? kMax( qw, rw )
                      : ( num == 2 && isCurrent ) ? kMax( repeat ? rw : 0, kMax( stop ? sw : 0, queue ? qw : 0 ) )
                      : ( num == 2 ) ? qw
                      : queue ? qw : repeat ? rw : stop ? sw : 0,
                   w2 = ( num == 3 ) ? sw
                      : ( num == 2 && !isCurrent ) ? sw
                      : 0; //phew

        //ellipse width, total width
        const uint ew = 16, tw = w1 + w2 + m * ( w2 ? 2 : 1 );
        p.setBrush( cg.highlight() );
        p.setPen( cg.highlight().dark() ); //TODO blend with background color
        p.drawEllipse( width - tw - ew/2, m / 2, ew, h );
        p.drawRect( width - tw, m / 2, tw, h );
        p.setPen( cg.highlight() );
        p.drawLine( width - tw, m/2 + 1, width - tw, h - m/2 );

        int x = width - m - mw, y = height() / 2, tmp = 0;
        const bool multi = ( isCurrent && num >= 2 );
        if( queue )
        {
            //draw the shadowed inner text
            //NOTE we can't set an arbituary font size or family, these settings are already optional
            //and user defaults should also take presidence if no playlist font has been selected
            //const QFont smallFont( "Arial", (playNext > 9) ? 9 : 12 );
            //p->setFont( smallFont );
            //TODO the shadow is hard to do well when using a dark font color
            //TODO it also looks cluttered for small font sizes
            //p->setPen( cg.highlightedText().dark() );
            //p->drawText( width - w + 2, 3, w, h-1, Qt::AlignCenter, str );

            if( !multi )
                tmp = -(qh / 2);
            y += tmp;
            p.setPen( cg.highlightedText() );
            p.drawText( x, y, -x + width, multi ? h/2 : qh, Qt::AlignCenter, str );
            y -= tmp;
            if( isCurrent )
                y -= height() / 2;
            else
                x -= m + w2;
        }
        if( repeat )
        {
            if( multi )
                tmp = (h/2 - rh)/2 + ( num == 2 && stop ? 0 : 1 );
            else
                tmp = -(rh / 2);
            y += tmp;
            p.drawPixmap( x, y, pixrepeat );
            y -= tmp;
            if( num == 3 )
            {
                x -= m + w2 + 2;
                y = height() / 2;
            }
            else
                y -= height() / 2;
        }
        if( stop )
        {
            if( multi && num != 3 )
                tmp = m + (h/2 - sh)/2;
            else
                tmp = -(sh / 2);
            y += tmp;
            p.drawPixmap( x, y, pixstop );
            y -= tmp;
        }
    }

    if( this != listView()->currentTrack() && !isSelected() )
    {
        p.setPen( QPen( cg.mid(), 0, Qt::SolidLine ) );
        p.drawLine( width - 1, 0, width - 1, height() - 1 );
    }

    p.end();
    painter->drawPixmap( 0, 0, buf );
}
Пример #4
0
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Draw info on selected item:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void drawMLinfo(){
	static u64 lastMenuChange = 0;
	static int lastSelected = -1;

	OSL_FONT *font = fontNormal;
	OSL_IMAGE *tmpCoverArt = NULL;

    if (mediaLibraryStatus != STATUS_QUERYMENU)
        return;

    skinGetPosition("POS_MEDIALIBRARY_INFO_BKG", tempPos);
    oslDrawImageXY(infoBkg, tempPos[0], tempPos[1]);
    oslSetFont(font);
    skinGetColor("RGBA_LABEL_TEXT", tempColor);
    skinGetColor("RGBA_LABEL_TEXT_SHADOW", tempColorShadow);
    setFontStyle(fontNormal, defaultTextSize, RGBA(tempColor[0], tempColor[1], tempColor[2], tempColor[3]), RGBA(tempColorShadow[0], tempColorShadow[1], tempColorShadow[2], tempColorShadow[3]), INTRAFONT_ALIGN_LEFT);

	switch (mlQueryType)
	{
	case QUERY_COUNT:
	case QUERY_COUNT_RATING:
	case QUERY_COUNT_ARTIST:
        skinGetPosition("POS_MEDIALIBRARY_TOTAL_TRACKS_LABEL", tempPos);
        oslDrawString(tempPos[0], tempPos[1], langGetString("TOTAL_TRACKS"));
        skinGetPosition("POS_MEDIALIBRARY_TOTAL_TIME_LABEL", tempPos);
        oslDrawString(tempPos[0], tempPos[1], langGetString("TOTAL_TIME"));
        skinGetColor("RGBA_TEXT", tempColor);
        skinGetColor("RGBA_TEXT_SHADOW", tempColorShadow);
        setFontStyle(fontNormal, defaultTextSize, RGBA(tempColor[0], tempColor[1], tempColor[2], tempColor[3]), RGBA(tempColorShadow[0], tempColorShadow[1], tempColorShadow[2], tempColorShadow[3]), INTRAFONT_ALIGN_LEFT);
        snprintf(buffer, sizeof(buffer), "%.f", MLresult[commonMenu.selected - mlBufferPosition]->intField01);
        skinGetPosition("POS_MEDIALIBRARY_TOTAL_TRACKS_VALUE", tempPos);
        oslDrawString(tempPos[0], tempPos[1], buffer);

        formatHHMMSS(MLresult[commonMenu.selected - mlBufferPosition]->intField02, buffer, sizeof(buffer));
        skinGetPosition("POS_MEDIALIBRARY_TOTAL_TIME_VALUE", tempPos);
        oslDrawString(tempPos[0], tempPos[1], buffer);
		break;
	case QUERY_SINGLE_ENTRY:
        skinGetPosition("POS_MEDIALIBRARY_GENRE_LABEL", tempPos);
        oslDrawString(tempPos[0], tempPos[1], langGetString("GENRE"));
        skinGetPosition("POS_MEDIALIBRARY_YEAR_LABEL", tempPos);
        oslDrawString(tempPos[0], tempPos[1], langGetString("YEAR"));
        skinGetPosition("POS_MEDIALIBRARY_TIME_LABEL", tempPos);
        oslDrawString(tempPos[0], tempPos[1], langGetString("TIME"));
        skinGetPosition("POS_MEDIALIBRARY_RATING_LABEL", tempPos);
        oslDrawString(tempPos[0], tempPos[1], langGetString("RATING"));
        skinGetPosition("POS_MEDIALIBRARY_PLAYED_LABEL", tempPos);
        oslDrawString(tempPos[0], tempPos[1], langGetString("PLAYED"));

        skinGetColor("RGBA_TEXT", tempColor);
        skinGetColor("RGBA_TEXT_SHADOW", tempColorShadow);
        setFontStyle(fontNormal, defaultTextSize, RGBA(tempColor[0], tempColor[1], tempColor[2], tempColor[3]), RGBA(tempColorShadow[0], tempColorShadow[1], tempColorShadow[2], tempColorShadow[3]), INTRAFONT_ALIGN_LEFT);
        skinGetPosition("POS_MEDIALIBRARY_GENRE_VALUE", tempPos);
        oslDrawString(tempPos[0], tempPos[1], MLresult[commonMenu.selected - mlBufferPosition]->genre);
        skinGetPosition("POS_MEDIALIBRARY_YEAR_VALUE", tempPos);
        oslDrawString(tempPos[0], tempPos[1], MLresult[commonMenu.selected - mlBufferPosition]->year);

        formatHHMMSS(MLresult[commonMenu.selected - mlBufferPosition]->seconds, buffer, sizeof(buffer));
        skinGetPosition("POS_MEDIALIBRARY_TIME_VALUE", tempPos);
        oslDrawString(tempPos[0], tempPos[1], buffer);

        skinGetPosition("POS_MEDIALIBRARY_RATING_VALUE", tempPos);
        drawRating(tempPos[0], tempPos[1], MLresult[commonMenu.selected - mlBufferPosition]->rating);

		skinGetPosition("POS_MEDIALIBRARY_PLAYED_VALUE", tempPos);
		snprintf(buffer, sizeof(buffer), "%i", MLresult[commonMenu.selected - mlBufferPosition]->played);
		oslDrawString(tempPos[0], tempPos[1], buffer);

		if (commonMenu.selected != lastSelected){
			sceRtcGetCurrentTick (&lastMenuChange);
			lastSelected = commonMenu.selected;
			if (coverArt){
				oslDeleteImage(coverArt);
				coverArt = NULL;
			}
			coverArtFailed = 0;
		}else if (!coverArt && !coverArtFailed){
			u64 currentTime;
			sceRtcGetCurrentTick(&currentTime);
			if (currentTime - lastMenuChange > COVERTART_DELAY){
				char dirName[264];
				int size = 0;

				cpuBoost();
				snprintf(dirName, sizeof(dirName), "%s", MLresult[commonMenu.selected - mlBufferPosition]->shortpath);
				directoryUp(dirName);
				//Look for folder.jpg in the same directory:
				snprintf(buffer, sizeof(buffer), "%s/%s", dirName, "folder.jpg");

				size = fileExists(buffer);
				if (size > 0 && size <= MAX_IMAGE_DIMENSION)
                {
					tmpCoverArt = oslLoadImageFileJPG(buffer, OSL_IN_RAM | OSL_SWIZZLED, OSL_PF_8888);
                }
				else
                {
					//Look for cover.jpg in same directory:
					snprintf(buffer, sizeof(buffer), "%s/%s", dirName, "cover.jpg");
					size = fileExists(buffer);
					if (size > 0 && size <= MAX_IMAGE_DIMENSION)
						tmpCoverArt = oslLoadImageFileJPG(buffer, OSL_IN_RAM | OSL_SWIZZLED, OSL_PF_8888);
				}
				if (tmpCoverArt){
    				int coverArtWidth  = skinGetParam("MEDIALIBRARY_COVERART_WIDTH");
    				int coverArtHeight = skinGetParam("MEDIALIBRARY_COVERART_HEIGHT");

					coverArt = oslScaleImageCreate(tmpCoverArt, OSL_IN_RAM | OSL_SWIZZLED, coverArtWidth, coverArtHeight, OSL_PF_8888);
					oslDeleteImage(tmpCoverArt);
					tmpCoverArt = NULL;

        			coverArt->stretchX = coverArtWidth;
        			coverArt->stretchY = coverArtHeight;
				}else{
					coverArtFailed = 1;
				}
				cpuRestore();
			}
		}

		if (coverArt){
			skinGetPosition("POS_MEDIALIBRARY_COVERART", tempPos);
			oslDrawImageXY(coverArt, tempPos[0], tempPos[1]);
		}
		break;
	}
}