Back to index

scribus-ng  1.3.4.dfsg+svn20071115
colorwheelwidget.cpp
Go to the documentation of this file.
00001 /*
00002 For general Scribus (>=1.3.2) copyright and licensing information please refer
00003 to the COPYING file provided with the program. Following this notice may exist
00004 a copyright and/or license notice that predates the release of Scribus 1.3.2
00005 for which a new license (GPL+exception) is in place.
00006 */
00007 
00008 #include "colorwheelwidget.h"
00009 #include "colorwheelwidget.moc"
00010 #include <qpainter.h>
00011 #include <qpixmap.h>
00012 #include <qimage.h>
00013 #include <math.h>
00014 
00015 #include "sccolor.h"
00016 #include "sccolorengine.h"
00017 
00018 ColorWheel::ColorWheel(QWidget * parent, const char * name) : QLabel(parent, name, WNoAutoErase)
00019 {
00020        currentDoc = NULL;
00021        currentColorSpace = colorModelRGB;
00022        baseAngle = 0;
00023        angleShift = 270;
00024        widthH = heightH = 150;
00025        // create color map
00026        colorMap.clear();
00027        // fit the colorMap 1st value with matrix beginning
00028        int mapIndex = angleShift;
00029        for (int i = 0; i < 360; ++i)
00030        {
00031               QColor c;
00032               c.setHsv(i, 255, 255);
00033               ScColor col;
00034               col.fromQColor(c);
00035               colorMap[mapIndex++] = col;
00036               if (mapIndex > 359)
00037                      mapIndex = 0;
00038        }
00039        actualColor = colorMap[0];
00040        trBaseColor = tr("Base Color");
00041 }
00042 
00043 void ColorWheel::mousePressEvent(QMouseEvent *e)
00044 {
00045        mouseReleaseEvent(e);
00046 }
00047 
00048 void ColorWheel::mouseMoveEvent(QMouseEvent *e)
00049 {
00050        mouseReleaseEvent(e);
00051 }
00052 
00053 void ColorWheel::mouseReleaseEvent(QMouseEvent *e)
00054 {
00055        baseAngle = valueFromPoint(e->pos());
00056        actualColor = colorMap[baseAngle];
00057        actualColor = ScColorEngine::convertToModel(actualColor, currentDoc, currentColorSpace);
00058        emit clicked(e->button(), e->pos());
00059 }
00060 
00061 void ColorWheel::paintEvent(QPaintEvent *)
00062 {
00063        paintWheel();
00064        paintCenterSample();
00065        makeColors();
00066 }
00067 
00068 void ColorWheel::makeColors()
00069 {
00070        if (currentType == Monochromatic)
00071               makeMonochromatic();
00072        if (currentType == Analogous)
00073               makeAnalogous();
00074        if (currentType == Complementary)
00075               makeComplementary();
00076        if (currentType == Split)
00077               makeSplit();
00078        if (currentType == Triadic)
00079               makeTriadic();
00080        if (currentType == Tetradic)
00081               makeTetradic();
00082 }
00083 
00084 void ColorWheel::paintCenterSample()
00085 {
00086        QPainter p;
00087        p.begin(this);
00088        p.setPen(QPen(Qt::black, 2));
00089        p.setBrush(ScColorEngine::getDisplayColor(actualColor, currentDoc ));
00090        p.drawEllipse(widthH - 20, heightH - 20, 40, 40);
00091        p.end();
00092 }
00093 
00094 void ColorWheel::paintWheel()
00095 {
00096        int h, s, v;
00097        QColor col(ScColorEngine::getDisplayColor(actualColor, currentDoc ));
00098        col.hsv(&h, &s, &v);
00099        int width = this->width();
00100        int height = this->height();
00101        QPainter p;
00102        p.begin(this);
00103        p.setWindow( 0, 0, width, height);
00104        p.fillRect(0, 0, width, height, Qt::white);
00105        p.setPen(Qt::black);
00106        p.drawRect(0, 0, width, height);
00107        // Half sizes
00108        heightH = height / 2;
00109        widthH = width / 2;
00110        for (int i = 0; i < 360; ++i)
00111        {
00112               QWMatrix matrix;
00113               matrix.translate(widthH, heightH);
00114               matrix.rotate((float)i);
00115               p.setWorldMatrix(matrix);
00116               QColor c;
00117               c.setHsv(i, 255, 255);
00118               p.setPen(QPen(c, 7));
00119               p.setBrush(c);
00120               p.drawLine(0, 0, 130, 0);
00121        }
00122 }
00123 
00124 QString ColorWheel::getTypeDescription(MethodType aType)
00125 {
00126        switch (aType)
00127        {
00128               case Monochromatic: return tr("Monochromatic");
00129               case Analogous: return tr("Analogous");
00130               case Complementary: return tr("Complementary");
00131               case Split: return tr("Split Complementary");
00132               case Triadic: return tr("Triadic");
00133               case Tetradic: return tr("Tetradic (Double Complementary)");
00134        }
00135        return "n/a";
00136 }
00137 
00138 ScColor ColorWheel::colorByAngle(int angle)
00139 {
00140        while (angle > 359)
00141               angle -= 359;
00142        while (angle < 0)
00143               angle += 359;
00144        return colorSpaceColor(colorMap[angle]);
00145 }
00146 
00147 ScColor ColorWheel::sampleByAngle(int angle)
00148 {
00149        while (angle > 359)
00150               angle -= 359;
00151        while (angle < 0)
00152               angle += 359;
00153        drawBorderPoint(angle);
00154        return colorSpaceColor(colorMap[angle]);
00155 }
00156 
00157 ScColor ColorWheel::colorSpaceColor(ScColor col)
00158 {
00159        QColor newcol;
00160        ScColor ret;
00161        int h, s, v;
00162 
00163        ScColorEngine::getRGBColor(col, currentDoc).getHsv(&h, &s, &v);
00164        newcol.setHsv(h, s, v);
00165        ret.fromQColor(newcol);
00166        ret = ScColorEngine::convertToModel(ret, currentDoc, currentColorSpace);
00167        return ret;
00168 }
00169 
00170 void ColorWheel::baseColor()
00171 {
00172        clearBorder();
00173        drawBorderPoint(baseAngle, true);
00174        paintCenterSample();
00175        colorList.clear();
00176        colorList[trBaseColor] = colorSpaceColor(actualColor);
00177 }
00178 
00179 void ColorWheel::makeMonochromatic()
00180 {
00181        baseColor();
00182        QColor col(ScColorEngine::getRGBColor(actualColor, currentDoc));
00183        ScColor l;
00184        l.fromQColor(col.light());
00185        l = ScColorEngine::convertToModel(l, currentDoc, currentColorSpace);
00186        colorList[tr("Monochromatic Light")] = l;
00187        l.fromQColor(col.dark());
00188        l = ScColorEngine::convertToModel(l, currentDoc, currentColorSpace);
00189        colorList[tr("Monochromatic Dark")] = l;
00190        currentType = Monochromatic;
00191 }
00192 
00193 void ColorWheel::makeAnalogous()
00194 {
00195        baseColor();
00196        colorList[tr("1st. Analogous")] = sampleByAngle(baseAngle + angle);
00197        colorList[tr("2nd. Analogous")] = sampleByAngle(baseAngle - angle);
00198        currentType = Analogous;
00199 }
00200 
00201 void ColorWheel::makeComplementary()
00202 {
00203        baseColor();
00204        colorList[tr("Complementary")] = sampleByAngle(baseAngle + 180);
00205        currentType = Complementary;
00206 }
00207 
00208 void ColorWheel::makeSplit()
00209 {
00210        baseColor();
00211        colorList[tr("1st. Split")] = sampleByAngle(baseAngle + angle);
00212        colorList[tr("2nd. Split")] = sampleByAngle(baseAngle - angle);
00213        colorList[tr("3rd. Split")] = sampleByAngle(baseAngle + 180 + angle);
00214        colorList[tr("4th. Split")] = sampleByAngle(baseAngle + 180 - angle);
00215        currentType = Split;
00216 }
00217 
00218 void ColorWheel::makeTriadic()
00219 {
00220        baseColor();
00221        colorList[tr("1st. Triadic")] = sampleByAngle(baseAngle + 120);
00222        colorList[tr("2nd. Triadic")] = sampleByAngle(baseAngle - 120);
00223        currentType = Triadic;
00224 }
00225 
00226 void ColorWheel::makeTetradic()
00227 {
00228        baseColor();
00229        colorList[tr("1st. Tetradic (base opposite)")] = sampleByAngle(baseAngle + 180);
00230        colorList[tr("2nd. Tetradic (angle)")] = sampleByAngle(baseAngle + angle);
00231        colorList[tr("3rd. Tetradic (angle opposite)")] = sampleByAngle(baseAngle + angle + 180);
00232        currentType = Tetradic;
00233 }
00234 
00235 void ColorWheel::clearBorder()
00236 {
00237        for (int i = 0; i < 360; ++i)
00238               drawBorderPoint(i, false, true);
00239 }
00240 
00241 void ColorWheel::drawBorderPoint(int angle, bool base, bool clear)
00242 {
00243        double r = 137.0;
00244        angle -= angleShift;
00245        double radang = M_PI * (double)angle/180.0;
00246        int x = (int)(r * cos(radang)) + widthH;
00247        int y = (int)(r * sin(radang)) + heightH;
00248        // draw border mark
00249        QPainter p;
00250        p.begin(this);
00251        if (clear)
00252        {
00253               p.setPen(QPen(Qt::white, 1));
00254               p.setBrush(Qt::white);
00255        }
00256        else
00257        {
00258               p.setPen(QPen(Qt::black, 1));
00259               if (base)
00260                      p.setBrush(Qt::red);
00261               else
00262                      p.setBrush(Qt::SolidPattern);
00263        }
00264        p.drawEllipse(x-4, y-4, 8, 8);
00265        p.end();
00266 }
00267 
00268 int ColorWheel::valueFromPoint(const QPoint & p) const
00269 {
00270        double yy = (double)heightH - (double)p.y();
00271        double xx = (double)p.x() - (double)widthH;
00272        double a = (xx || yy) ? atan2(yy, xx) : 0.0;
00273 
00274        if ( a < M_PI/-2 )
00275               a = a + M_PI * 2;
00276 
00277        int dist = 0;
00278        int minv = 0, maxv = 359;
00279        int r = maxv - minv;
00280        int val;
00281 
00282        val = (int)(0.5 + minv + r * (M_PI * 3/2 -a) / (2 * M_PI));
00283 
00284        if ( dist > 0 )
00285               val -= dist;
00286 
00287        return val;
00288 }
00289 
00290 bool ColorWheel::recomputeColor(ScColor col)
00291 {
00292        int origh, origs, origv;
00293        ColorMap::iterator it;
00294        QColor c(ScColorEngine::getRGBColor(col, currentDoc));
00295        QColor act(ScColorEngine::getRGBColor(actualColor, currentDoc));
00296 
00297        c.hsv(&origh, &origs, &origv);
00298        for (it = colorMap.begin(); it != colorMap.end(); ++it)
00299        {
00300               int tmph, tmps, tmpv;
00301               QColor col(ScColorEngine::getRGBColor(it.data(), currentDoc));
00302               col.hsv(&tmph, &tmps, &tmpv);
00303               if (origh == tmph)
00304               {
00305                      act.setHsv(tmph, origs, origv);
00306                      actualColor.fromQColor(act);
00307                      actualColor = ScColorEngine::convertToModel(actualColor, currentDoc, currentColorSpace);
00308                      baseAngle = it.key();
00309                      return true;
00310               }
00311        }
00312        return false;
00313 }