void KisColorSelectorRing::paintCache() { QImage cache(m_cachedSize, m_cachedSize, QImage::Format_ARGB32_Premultiplied); Eigen::Vector2i center(cache.width()/2., cache.height()/2.); for(int x=0; x<cache.width(); x++) { for(int y=0; y<cache.height(); y++) { Eigen::Vector2i currentPoint((float)x, (float)y); Eigen::Vector2i relativeVector = currentPoint-center; qreal currentRadius = relativeVector.squaredNorm(); currentRadius=sqrt(currentRadius); if(currentRadius < outerRadius()+1 && currentRadius > innerRadius()-1) { float angle = std::atan2((float)relativeVector.y(), (float)relativeVector.x())+((float)M_PI); angle/=2*((float)M_PI); angle*=359.f; if(currentRadius < outerRadius() && currentRadius > innerRadius()) { cache.setPixel(x, y, m_cachedColors.at(angle)); } else { // draw antialiased border qreal coef=1.; if(currentRadius > outerRadius()) { // outer border coef-=currentRadius; coef+=outerRadius(); } else { // inner border coef+=currentRadius; coef-=innerRadius(); } coef=qBound(qreal(0.), coef, qreal(1.)); int red=qRed(m_cachedColors.at(angle)); int green=qGreen(m_cachedColors.at(angle)); int blue=qBlue(m_cachedColors.at(angle)); // the format is premultiplied, so we have to take care of that QRgb color = qRgba(red*coef, green*coef, blue*coef, 255*coef); cache.setPixel(x, y, color); } } else { cache.setPixel(x, y, qRgba(0,0,0,0)); } } } m_pixelCache = cache; }
void KisColorSelectorRing::paint(QPainter* painter) { if(isDirty()) { m_cachedColorSpace = colorSpace(); m_cachedSize=qMin(width(), height()); colorCache(); paintCache(); } int size = qMin(width(), height()); if(m_cachedSize!=size) { m_cachedSize=size; paintCache(); } painter->drawImage(width()/2-m_pixelCache.width()/2, height()/2-m_pixelCache.height()/2, m_pixelCache); // paint blip if(m_parent->displayBlip()) { qreal angle; int y_start, y_end, x_start, x_end; angle=m_lastHue*2.*M_PI+(M_PI); y_start=innerRadius()*sin(angle)+height()/2; y_end=outerRadius()*sin(angle)+height()/2; x_start=innerRadius()*cos(angle)+width()/2; x_end=outerRadius()*cos(angle)+width()/2; painter->setPen(QColor(0,0,0)); painter->drawLine(x_start, y_start, x_end, y_end); angle+=M_PI/180.; y_start=innerRadius()*sin(angle)+height()/2; y_end=outerRadius()*sin(angle)+height()/2; x_start=innerRadius()*cos(angle)+width()/2; x_end=outerRadius()*cos(angle)+width()/2; painter->setPen(QColor(255,255,255)); painter->drawLine(x_start, y_start, x_end, y_end); } }
bool KisColorSelectorRing::containsPointInComponentCoords(int x, int y) const { int outerRadiusSquared = qMin(width(), height())/2; int innerRadiusSquared = innerRadius(); outerRadiusSquared*=outerRadiusSquared; innerRadiusSquared*=innerRadiusSquared; Eigen::Vector2i relativeVector(x-width()/2, y-height()/2); if(relativeVector.squaredNorm() < outerRadiusSquared && relativeVector.squaredNorm() > innerRadiusSquared) { return true; } return false; }
void SunMenuItemView::updateShape() { QPainterPath newPath; qreal tmp = qAbs(sweepLength()); if (width() != 0 && tmp > 0.001) { qint32 innerRad = innerRadius(); qint32 outerRadius = innerRad + width(); QRectF r = QRect(-outerRadius, -outerRadius, outerRadius * 2, outerRadius * 2); if (innerRad == 0 && qAbs(sweepLength() - 360) < 0.0001) { newPath.addEllipse(r); } else { newPath.arcMoveTo(r, startAngle()); newPath.arcTo(r, startAngle(), sweepLength()); if(innerRad == 0) { newPath.lineTo(0,0); }else { r = QRect(-innerRad, -innerRad, innerRad * 2, innerRad * 2); newPath.arcTo(r, startAngle() + sweepLength(), -sweepLength()); } newPath.closeSubpath(); } } // setPath(newPath); reinitializeDisplayedItemPosition(); }
void knob::drawKnob( QPainter * _p ) { if( updateAngle() == false && !m_cache.isNull() ) { _p->drawImage( 0, 0, m_cache ); return; } m_cache = QImage( size(), QImage::Format_ARGB32 ); m_cache.fill( qRgba( 0, 0, 0, 0 ) ); QPainter p( &m_cache ); QPoint mid; if( m_knobNum == knobStyled ) { p.setRenderHint( QPainter::Antialiasing ); // Perhaps this can move to setOuterRadius() if( m_outerColor ) { QRadialGradient gradient( centerPoint(), outerRadius() ); gradient.setColorAt(0.4, _p->pen().brush().color() ); gradient.setColorAt(1, *m_outerColor ); p.setPen( QPen( gradient, lineWidth(), Qt::SolidLine, Qt::RoundCap ) ); } else { QPen pen = p.pen(); pen.setWidth( (int) lineWidth() ); pen.setCapStyle( Qt::RoundCap ); p.setPen( pen ); } p.drawLine( calculateLine( centerPoint(), outerRadius(), innerRadius() ) ); p.end(); _p->drawImage( 0, 0, m_cache ); return; } // Old-skool knobs const float radius = m_knobPixmap->width() / 2.0f - 1; mid = QPoint( width() / 2, m_knobPixmap->height() / 2 ); p.drawPixmap( static_cast<int>( width() / 2 - m_knobPixmap->width() / 2 ), 0, *m_knobPixmap ); p.setRenderHint( QPainter::Antialiasing ); const int centerAngle = angleFromValue( model()->centerValue(), model()->minValue(), model()->maxValue(), m_totalAngle ); const int arcLineWidth = 2; const int arcRectSize = m_knobPixmap->width() - arcLineWidth; QColor col; if( m_knobNum == knobVintage_32 ) { col = QApplication::palette().color( QPalette::Active, QPalette::Shadow ); } else { col = QApplication::palette().color( QPalette::Active, QPalette::WindowText ); } col.setAlpha( 70 ); p.setPen( QPen( col, 2 ) ); p.drawArc( mid.x() - arcRectSize/2, 1, arcRectSize, arcRectSize, 315*16, 16*m_totalAngle ); switch( m_knobNum ) { case knobSmall_17: { p.setPen( QPen( QApplication::palette().color( QPalette::Active, QPalette::WindowText ), 2 ) ); p.drawLine( calculateLine( mid, radius-2 ) ); break; } case knobBright_26: { p.setPen( QPen( QApplication::palette().color( QPalette::Active, QPalette::WindowText ), 2 ) ); p.drawLine( calculateLine( mid, radius-5 ) ); break; } case knobDark_28: { p.setPen( QPen( QApplication::palette().color( QPalette::Active, QPalette::WindowText ), 2 ) ); const float rb = qMax<float>( ( radius - 10 ) / 3.0, 0.0 ); const float re = qMax<float>( ( radius - 4 ), 0.0 ); QLineF ln = calculateLine( mid, re, rb ); ln.translate( 1, 1 ); p.drawLine( ln ); break; } case knobGreen_17: { p.setPen( QPen( QApplication::palette().color( QPalette::Active, QPalette::BrightText), 2 ) ); p.drawLine( calculateLine( mid, radius ) ); break; } case knobVintage_32: { p.setPen( QPen( QApplication::palette().color( QPalette::Active, QPalette::Shadow), 2 ) ); p.drawLine( calculateLine( mid, radius-2, 2 ) ); break; } } p.drawArc( mid.x() - arcRectSize/2, 1, arcRectSize, arcRectSize, (90-centerAngle)*16, -16*(m_angle-centerAngle) ); p.end(); _p->drawImage( 0, 0, m_cache ); }
void SunMenuItemView::reinitializeDisplayedItemPosition() { qint32 maxWidth = width(); qint32 maxHeight; QGraphicsItem* gi = displayedItem()->graphicsItem(); //default gi->resetTransform(); // Calculate maxHeight as smaller chord(only for small sweepLengths) if (sweepLength() <= 90) { qreal biggerChord = 2 * (innerRadius() + maxWidth) * /*qAbs*/(qSin((M_PI / 180) * sweepLength() / 2)); qreal smallerChord = 2 * innerRadius() * /*qAbs*/(qSin((M_PI / 180) * sweepLength() / 2)); maxHeight = (0.2 * smallerChord + 1.4 * biggerChord) / 2; } else maxHeight = displayedItem()->maximumHeight(); //hide item if it too small if (maxWidth < 10 || maxHeight < 5) { gi->hide(); return; } QRectF graphicsItemRect; if (sweepLength() == 360 && innerRadius() == 0) { displayedItem()->setMaximumSize(2 * maxWidth /*diameter*/, maxHeight); graphicsItemRect = gi->boundingRect(); gi->setPos(-graphicsItemRect.width() / 2, -graphicsItemRect.height() / 2); gi->show(); return; } displayedItem()->setMaximumSize(maxWidth - 10, maxHeight); graphicsItemRect = gi->boundingRect(); ///////////////////////////////////////////////////////////////////////////////// //positioning mDisplayedItem (rotation and coordinates). qreal rotationAngle = startAngle() + sweepLength() / 2; // Getting distance and angle (polar coordinates) + some centering adjustments // We assume that (0,0) item's coordinate is it's top left corner //(like QGraphicsSimpleTextItem and QGraphicsProxyWidget). qreal angle, distance; if (rotationAngle >= 270 || rotationAngle <= 90) { distance = innerRadius() + maxWidth / 2 - graphicsItemRect.width() / 2; angle = rotationAngle + (180 / M_PI) * qAtan(graphicsItemRect.height() / (2 * distance)); } else { distance = innerRadius() + maxWidth / 2 + graphicsItemRect.width() / 2; angle = rotationAngle - (180 / M_PI) * qAtan(graphicsItemRect.height() / (2 * distance)); rotationAngle -= 180; } gi->setPos(distance * qCos((M_PI / 180) * angle), -distance * qSin((M_PI / 180) * angle)); gi->setRotation(-rotationAngle); //minus - because this function rotates clockwise. gi->show(); /////////////////////////////////////////////////////////////////////////////////// }