void QwtPainter::drawColoredArc(QPainter *painter, const QRect &rect, int peak, int arc, int interval, const QColor &c1, const QColor &c2) { int h1, s1, v1; int h2, s2, v2; #if QT_VERSION < 0x040000 c1.hsv(&h1, &s1, &v1); c2.hsv(&h2, &s2, &v2); #else c1.getHsv(&h1, &s1, &v1); c2.getHsv(&h2, &s2, &v2); #endif arc /= 2; for ( int angle = -arc; angle < arc; angle += interval) { double ratio; if ( angle >= 0 ) ratio = 1.0 - angle / double(arc); else ratio = 1.0 + angle / double(arc); QColor c; c.setHsv( h1 + qRound(ratio * (h2 - h1)), s1 + qRound(ratio * (s2 - s1)), v1 + qRound(ratio * (v2 - v1)) ); painter->setPen(QPen(c, painter->pen().width())); painter->drawArc(rect, (peak + angle) * 16, interval * 16); } }
/*! Mixes two colors \a c1 and \a c2 to a new color. */ QColor QPlatinumStyle::mixedColor(const QColor &c1, const QColor &c2) const { int h1,s1,v1,h2,s2,v2; c1.hsv(&h1,&s1,&v1); c2.hsv(&h2,&s2,&v2); return QColor( (h1+h2)/2, (s1+s2)/2, (v1+v2)/2, QColor::Hsv ); }
/*! Draw a dotted round circle, if !isReadOnly() \param painter Painter */ void QwtDial::drawFocusIndicator(QPainter *painter) const { if ( !isReadOnly() ) { QRect focusRect = contentsRect(); const int margin = 2; focusRect.setRect( focusRect.x() + margin, focusRect.y() + margin, focusRect.width() - 2 * margin, focusRect.height() - 2 * margin); QColor color = colorGroup().color(QColorGroup::Base); if (color.isValid()) { int h, s, v; color.hsv(&h, &s, &v); color = (v > 128) ? Qt::gray.dark(120) : Qt::gray.light(120); } else color = Qt::darkGray; painter->save(); painter->setBrush(Qt::NoBrush); painter->setPen(QPen(color, 0, Qt::DotLine)); painter->drawEllipse(focusRect); painter->restore(); } }
void BatteryStatus::drawSegment( QPainter *p, const QRect &r, const QColor &topgrad, const QColor &botgrad, const QColor &highlight, int hightlight_height ) { int h1, h2, s1, s2, v1, v2, ng = r.height(), hy = ng*30/100, hh = hightlight_height; topgrad.hsv( &h1, &s1, &v1 ); botgrad.hsv( &h2, &s2, &v2 ); for ( int j = 0; j < hy-2; j++ ) { p->setPen( QColor( h1 + ((h2-h1)*j)/(ng-1), s1 + ((s2-s1)*j)/(ng-1), v1 + ((v2-v1)*j)/(ng-1), QColor::Hsv ) ); p->drawLine( r.x(), r.top()+hy-2-j, r.x()+r.width(), r.top()+hy-2-j ); } for ( int j = 0; j < hh; j++ ) { p->setPen( highlight ); p->drawLine( r.x(), r.top()+hy-2+j, r.x()+r.width(), r.top()+hy-2+j ); } for ( int j = 0; j < ng-hy-hh; j++ ) { p->setPen( QColor( h1 + ((h2-h1)*j)/(ng-1), s1 + ((s2-s1)*j)/(ng-1), v1 + ((v2-v1)*j)/(ng-1), QColor::Hsv ) ); p->drawLine( r.x(), r.top()+hy+hh-2+j, r.x()+r.width(), r.top()+hy+hh-2+j ); } }
QColor PrettyPopupMenu::calcPixmapColor() { KConfig *config = KGlobal::config(); config->setGroup("WM"); QColor color = QApplication::palette().active().highlight(); // QColor activeTitle = QApplication::palette().active().background(); // QColor inactiveTitle = QApplication::palette().inactive().background(); QColor activeTitle = config->readColorEntry("activeBackground", &color); QColor inactiveTitle = config->readColorEntry("inactiveBackground", &color); // figure out which color is most suitable for recoloring to int h1, s1, v1, h2, s2, v2, h3, s3, v3; activeTitle.hsv(&h1, &s1, &v1); inactiveTitle.hsv(&h2, &s2, &v2); QApplication::palette().active().background().hsv(&h3, &s3, &v3); if ( (kAbs(h1-h3)+kAbs(s1-s3)+kAbs(v1-v3) < kAbs(h2-h3)+kAbs(s2-s3)+kAbs(v2-v3)) && ((kAbs(h1-h3)+kAbs(s1-s3)+kAbs(v1-v3) < 32) || (s1 < 32)) && (s2 > s1)) color = inactiveTitle; else color = activeTitle; // limit max/min brightness int r, g, b; color.rgb(&r, &g, &b); int gray = qGray(r, g, b); if (gray > 180) { r = (r - (gray - 180) < 0 ? 0 : r - (gray - 180)); g = (g - (gray - 180) < 0 ? 0 : g - (gray - 180)); b = (b - (gray - 180) < 0 ? 0 : b - (gray - 180)); } else if (gray < 76) { r = (r + (76 - gray) > 255 ? 255 : r + (76 - gray)); g = (g + (76 - gray) > 255 ? 255 : g + (76 - gray)); b = (b + (76 - gray) > 255 ? 255 : b + (76 - gray)); } color.setRgb(r, g, b); return color; }
QColor KGlobalSettings::calculateAlternateBackgroundColor(const QColor& base) { if (base == Qt::white) return QColor(238,246,255); else { int h, s, v; base.hsv( &h, &s, &v ); if (v > 128) return base.dark(106); else if (base != Qt::black) return base.light(110); return QColor(32,32,32); } }
ClusterPalette::ClusterPalette(QColor backgroundColor,QWidget* parent,KStatusBar * statusBar, const char* name, WFlags fl ) : QVBox( parent, name, fl ),doc(0L),mode(IMMEDIATE),isInSelectItems(false),isUpToDate(true),backgroundColor(backgroundColor),statusBar(statusBar),isInUserClusterInfoMode(false) { //Set the palette color setPaletteBackgroundColor(backgroundColor); setPaletteForegroundColor(white); iconView = new QIconView(this, "ClusterPalette"); QFont font( "Helvetica",8); iconView->setFont(font); iconView->setFrameStyle(QFrame::NoFrame); iconView->setArrangement(QIconView::LeftToRight); iconView->setResizeMode(QIconView::Adjust); iconView->setPaletteBackgroundColor(backgroundColor); iconView->setHScrollBarMode(QScrollView::AlwaysOff); iconView->setVScrollBarMode(QScrollView::AlwaysOff); int h; int s; int v; backgroundColor.hsv(&h,&s,&v); if(s <= 80 && v >= 240 || (s <= 40 && v >= 220)) iconView->setPaletteForegroundColor(black); else iconView->setPaletteForegroundColor(white); iconView->setSelectionMode(QIconView::Extended); iconView->setItemsMovable(false); iconView->setSpacing(4); QFontInfo fontInfo = QFontInfo(QFont()); iconView->setGridX(fontInfo.pixelSize() * 2); iconView->setGridY(15); iconView->arrangeItemsInGrid(); //Deal with the sizes setSizePolicy(QSizePolicy((QSizePolicy::SizeType)5,(QSizePolicy::SizeType)5)); //Set the legend in the good language languageChange(); //Signal and slot connection connect(iconView,SIGNAL(contextMenuRequested(QIconViewItem* ,const QPoint&)),this, SLOT(slotRightPressed(QIconViewItem*))); connect(iconView,SIGNAL(selectionChanged()),this, SLOT(slotClickRedraw())); connect(iconView,SIGNAL(mouseButtonPressed(int,QIconViewItem* ,const QPoint&)),this, SLOT(slotMousePressed(int,QIconViewItem*))); connect(iconView,SIGNAL(onItem(QIconViewItem*)),this, SLOT(slotOnItem(QIconViewItem*))); }
QPalette::QPalette( const QColor &button, const QColor &background ) { data = new QPalData; Q_CHECK_PTR( data ); data->ser_no = palette_count++; QColor bg = background, btn = button, fg, base, disfg; int h, s, v; bg.hsv( &h, &s, &v ); if ( v > 128 ) { // light background fg = Qt::black; base = Qt::white; disfg = Qt::darkGray; } else { // dark background fg = Qt::white; base = Qt::black; disfg = Qt::darkGray; } data->active = QColorGroup( fg, btn, btn.light(150), btn.dark(), btn.dark(150), fg, Qt::white, base, bg ); data->disabled = QColorGroup( disfg, btn, btn.light(150), btn.dark(), btn.dark(150), disfg, Qt::white, base, bg ); data->inactive = data->active; }
void KZColorSelector::setBaseColor(const QColor& color) { color.hsv(&baseColorH, &baseColorS, &baseColorV); }
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 ); }