krita/ui

kis_autogradient_resource.cc

Go to the documentation of this file.
00001 /*
00002  *  Copyright (c) 2004 Cyrille Berger <cberger@cberger.net>
00003  *                2004 Sven Langkamp <sven.langkamp@gmail.com>
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  */
00019 
00020 #include "kis_autogradient_resource.h"
00021 
00022 #include "KoColorSpaceRegistry.h"
00023 #include "KoColorSpace.h"
00024 
00025 // XXX: use the same #define as in kis_gradient.cc, probably best customizable?
00026 #define PREVIEW_WIDTH 64
00027 #define PREVIEW_HEIGHT 64
00028 
00029 
00030 void KisAutogradientResource::createSegment(int interpolation, int colorInterpolation, double startOffset, double endOffset, double middleOffset, const QColor & left, const QColor & right)
00031 {
00032     pushSegment(new KoGradientSegment(interpolation, colorInterpolation, startOffset, middleOffset, endOffset, KoColor(left, colorSpace()), KoColor(right, colorSpace())));
00033 
00034 }
00035 
00036 const QList<double> KisAutogradientResource::getHandlePositions() const
00037 {
00038     QList<double> handlePositions;
00039 
00040     handlePositions.push_back(m_segments[0]->startOffset());
00041     for (int i = 0; i < m_segments.count(); i++) {
00042         handlePositions.push_back(m_segments[i]->endOffset());
00043     }
00044     return handlePositions;
00045 }
00046 
00047 const QList<double> KisAutogradientResource::getMiddleHandlePositions() const
00048 {
00049     QList<double> middleHandlePositions;
00050 
00051     for (int i = 0; i < m_segments.count(); i++) {
00052         middleHandlePositions.push_back(m_segments[i]->middleOffset());
00053     }
00054     return middleHandlePositions;
00055 }
00056 
00057 void KisAutogradientResource::moveSegmentStartOffset(KoGradientSegment* segment, double t)
00058 {
00059     QList<KoGradientSegment*>::iterator it = qFind(m_segments.begin(), m_segments.end(), segment);
00060     if (it != m_segments.end()) {
00061         if (it == m_segments.begin()) {
00062             segment->setStartOffset(0.0);
00063             return;
00064         }
00065         KoGradientSegment* previousSegment = (*(it - 1));
00066         if (t > segment->startOffset()) {
00067             if (t > segment->middleOffset())
00068                 t = segment->middleOffset();
00069         } else {
00070             if (t < previousSegment->middleOffset())
00071                 t = previousSegment->middleOffset();
00072         }
00073         previousSegment->setEndOffset(t);
00074         segment->setStartOffset(t);
00075     }
00076 }
00077 
00078 void KisAutogradientResource::moveSegmentEndOffset(KoGradientSegment* segment, double t)
00079 {
00080     QList<KoGradientSegment*>::iterator it = qFind(m_segments.begin(), m_segments.end(), segment);
00081     if (it != m_segments.end()) {
00082         if (it + 1 == m_segments.end()) {
00083             segment->setEndOffset(1.0);
00084             return;
00085         }
00086         KoGradientSegment* followingSegment = (*(it + 1));
00087         if (t < segment->endOffset()) {
00088             if (t < segment->middleOffset())
00089                 t = segment->middleOffset();
00090         } else {
00091             if (t > followingSegment->middleOffset())
00092                 t = followingSegment->middleOffset();
00093         }
00094         followingSegment->setStartOffset(t);
00095         segment->setEndOffset(t);
00096     }
00097 }
00098 
00099 void KisAutogradientResource::moveSegmentMiddleOffset(KoGradientSegment* segment, double t)
00100 {
00101     if (segment) {
00102         if (t > segment->endOffset())
00103             segment->setMiddleOffset(segment->endOffset());
00104         else if (t < segment->startOffset())
00105             segment->setMiddleOffset(segment->startOffset());
00106         else
00107             segment->setMiddleOffset(t);
00108     }
00109 }
00110 
00111 void KisAutogradientResource::splitSegment(KoGradientSegment* segment)
00112 {
00113     Q_ASSERT(segment != 0);
00114     QList<KoGradientSegment*>::iterator it = qFind(m_segments.begin(), m_segments.end(), segment);
00115     if (it != m_segments.end()) {
00116         KoColor midleoffsetColor(segment->endColor().colorSpace());
00117         segment->colorAt(midleoffsetColor, segment->middleOffset());
00118         KoGradientSegment* newSegment = new KoGradientSegment(
00119             segment->interpolation(), segment->colorInterpolation(),
00120             segment ->startOffset(),
00121             (segment->middleOffset() - segment->startOffset()) / 2 + segment->startOffset(),
00122             segment->middleOffset(),
00123             segment->startColor(),
00124             midleoffsetColor);
00125         m_segments.insert(it, newSegment);
00126         segment->setStartColor(midleoffsetColor);
00127         segment->setStartOffset(segment->middleOffset());
00128         segment->setMiddleOffset((segment->endOffset() - segment->startOffset()) / 2 + segment->startOffset());
00129     }
00130 }
00131 
00132 void KisAutogradientResource::duplicateSegment(KoGradientSegment* segment)
00133 {
00134     Q_ASSERT(segment != 0);
00135     QList<KoGradientSegment*>::iterator it = qFind(m_segments.begin(), m_segments.end(), segment);
00136     if (it != m_segments.end()) {
00137         double middlePostionPercentage = (segment->middleOffset() - segment->startOffset()) / segment->length();
00138         double center = segment->startOffset() + segment->length() / 2;
00139         KoGradientSegment* newSegment = new KoGradientSegment(
00140             segment->interpolation(), segment->colorInterpolation(),
00141             segment ->startOffset(),
00142             segment->length() / 2 * middlePostionPercentage + segment->startOffset(),
00143             center, segment->startColor(),
00144             segment->endColor());
00145         m_segments.insert(it, newSegment);
00146         segment->setStartOffset(center);
00147         segment->setMiddleOffset(segment->length() * middlePostionPercentage  + segment->startOffset());
00148     }
00149 }
00150 
00151 void KisAutogradientResource::mirrorSegment(KoGradientSegment* segment)
00152 {
00153     Q_ASSERT(segment != 0);
00154     KoColor tmpColor = segment->startColor();
00155     segment->setStartColor(segment->endColor());
00156     segment->setEndColor(tmpColor);
00157     segment->setMiddleOffset(segment->endOffset() - (segment->middleOffset() - segment->startOffset()));
00158 
00159     if (segment->interpolation() == INTERP_SPHERE_INCREASING)
00160         segment->setInterpolation(INTERP_SPHERE_DECREASING);
00161     else if (segment->interpolation() == INTERP_SPHERE_DECREASING)
00162         segment->setInterpolation(INTERP_SPHERE_INCREASING);
00163 
00164     if (segment->colorInterpolation() == COLOR_INTERP_HSV_CW)
00165         segment->setColorInterpolation(COLOR_INTERP_HSV_CCW);
00166     else if (segment->colorInterpolation() == COLOR_INTERP_HSV_CCW)
00167         segment->setColorInterpolation(COLOR_INTERP_HSV_CW);
00168 }
00169 
00170 KoGradientSegment* KisAutogradientResource::removeSegment(KoGradientSegment* segment)
00171 {
00172     Q_ASSERT(segment != 0);
00173     if (m_segments.count() < 2)
00174         return 0;
00175     QList<KoGradientSegment*>::iterator it = qFind(m_segments.begin(), m_segments.end(), segment);
00176     if (it != m_segments.end()) {
00177         double middlePostionPercentage;
00178         KoGradientSegment* nextSegment;
00179         if (it == m_segments.begin()) {
00180             nextSegment = (*(it + 1));
00181             middlePostionPercentage = (nextSegment->middleOffset() - nextSegment->startOffset()) / nextSegment->length();
00182             nextSegment->setStartOffset(segment->startOffset());
00183             nextSegment->setMiddleOffset(middlePostionPercentage * nextSegment->length() + nextSegment->startOffset());
00184         } else {
00185             nextSegment = (*(it - 1));
00186             middlePostionPercentage = (nextSegment->middleOffset() - nextSegment->startOffset()) / nextSegment->length();
00187             nextSegment->setEndOffset(segment->endOffset());
00188             nextSegment->setMiddleOffset(middlePostionPercentage * nextSegment->length() + nextSegment->startOffset());
00189         }
00190 
00191         delete segment;
00192         m_segments.erase(it);
00193         return nextSegment;
00194     }
00195     return 0;
00196 }
00197 
00198 bool KisAutogradientResource::removeSegmentPossible() const
00199 {
00200     if (m_segments.count() < 2)
00201         return false;
00202     return true;
00203 }