krita

kis_autogradient_resource.cc

00001 /*
00002  *  Copyright (c) 2004 Cyrille Berger <cberger@cberger.net>
00003  *                2004 Sven Langkamp <longamp@reallygood.de>
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_gradient.h"
00021 #include "kis_autogradient_resource.h"
00022 
00023 // FIXME: use the same #define as in kis_gradient.cc, probably best customizable?
00024 #define PREVIEW_WIDTH 64
00025 #define PREVIEW_HEIGHT 64
00026 
00027 
00028 void KisAutogradientResource::createSegment( int interpolation, int colorInterpolation, double startOffset, double endOffset, double middleOffset, QColor left, QColor right )
00029 {
00030     pushSegment(new KisGradientSegment(interpolation, colorInterpolation, startOffset, middleOffset, endOffset, Color( left, 1 ), Color( right, 1 )));
00031 
00032 }
00033 
00034 const QValueVector<double> KisAutogradientResource::getHandlePositions() const
00035 {
00036     QValueVector<double> handlePositions;
00037 
00038     handlePositions.push_back(m_segments[0]->startOffset());
00039     for (uint i = 0; i < m_segments.count(); i++)
00040     {
00041         handlePositions.push_back(m_segments[i]->endOffset());
00042     }
00043     return handlePositions;
00044 }
00045 
00046 const QValueVector<double> KisAutogradientResource::getMiddleHandlePositions() const
00047 {
00048     QValueVector<double> middleHandlePositions;
00049 
00050     for (uint i = 0; i < m_segments.count(); i++)
00051     {
00052         middleHandlePositions.push_back(m_segments[i]->middleOffset());
00053     }
00054     return middleHandlePositions;
00055 }
00056 
00057 void KisAutogradientResource::moveSegmentStartOffset( KisGradientSegment* segment, double t)
00058 {
00059     QValueVector<KisGradientSegment*>::iterator it = qFind( m_segments.begin(), m_segments.end(), segment );
00060     if ( it != m_segments.end() )
00061     {
00062         if ( it == m_segments.begin() )
00063         {
00064             segment->setStartOffset( 0.0 );
00065             return;
00066         }
00067         KisGradientSegment* previousSegment = (*(it-1));
00068         if ( t > segment->startOffset()  )
00069         {
00070             if( t > segment->middleOffset() )
00071                 t = segment->middleOffset();
00072         }
00073         else {
00074             if( t < previousSegment->middleOffset() )
00075                 t = previousSegment->middleOffset();
00076         }
00077         previousSegment->setEndOffset( t );
00078         segment->setStartOffset( t );
00079     }
00080 }
00081 
00082 void KisAutogradientResource::moveSegmentEndOffset( KisGradientSegment* segment, double t)
00083 {
00084     QValueVector<KisGradientSegment*>::iterator it = qFind( m_segments.begin(), m_segments.end(), segment );
00085     if ( it != m_segments.end() )
00086     {
00087         if ( it+1 == m_segments.end() )
00088         {
00089             segment->setEndOffset( 1.0 );
00090             return;
00091         }
00092         KisGradientSegment* followingSegment = (*(it+1));
00093         if ( t < segment->endOffset() )
00094         {
00095             if( t < segment->middleOffset() )
00096                 t = segment->middleOffset();
00097         }
00098         else {
00099             if( t > followingSegment->middleOffset() )
00100                 t = followingSegment->middleOffset();
00101         }
00102         followingSegment->setStartOffset( t );
00103         segment->setEndOffset( t );
00104     }
00105 }
00106 
00107 void KisAutogradientResource::moveSegmentMiddleOffset( KisGradientSegment* segment, double t)
00108 {
00109     if( segment )
00110     {
00111         if( t > segment->endOffset() )
00112             segment->setMiddleOffset( segment->endOffset() );
00113         else if( t < segment->startOffset() )
00114             segment->setMiddleOffset( segment->startOffset() );
00115         else
00116             segment->setMiddleOffset( t );
00117     }
00118 }
00119 
00120 void KisAutogradientResource::splitSegment( KisGradientSegment* segment )
00121 {
00122     Q_ASSERT(segment != 0);
00123     QValueVector<KisGradientSegment*>::iterator it = qFind( m_segments.begin(), m_segments.end(), segment );
00124     if ( it != m_segments.end() )
00125     {
00126         KisGradientSegment* newSegment = new KisGradientSegment(
00127                 segment->interpolation(), segment->colorInterpolation(),
00128                 segment ->startOffset(),
00129                 ( segment->middleOffset() - segment->startOffset() ) / 2 + segment->startOffset(),
00130                 segment->middleOffset(),
00131                 segment->startColor(),
00132                 segment->colorAt( segment->middleOffset() ) );
00133         m_segments.insert( it, newSegment );
00134         segment->setStartColor( segment->colorAt( segment->middleOffset() ) );
00135         segment->setStartOffset( segment->middleOffset() );
00136         segment->setMiddleOffset( ( segment->endOffset() - segment->startOffset() ) / 2 + segment->startOffset() );
00137     }
00138 }
00139 
00140 void KisAutogradientResource::duplicateSegment( KisGradientSegment* segment )
00141 {
00142     Q_ASSERT(segment != 0);
00143     QValueVector<KisGradientSegment*>::iterator it = qFind( m_segments.begin(), m_segments.end(), segment );
00144     if ( it != m_segments.end() )
00145     {
00146         double middlePostionPercentage = ( segment->middleOffset() - segment->startOffset() ) / segment->length();
00147         double center = segment->startOffset() + segment->length() / 2;
00148         KisGradientSegment* newSegment = new KisGradientSegment(
00149                 segment->interpolation(), segment->colorInterpolation(),
00150                 segment ->startOffset(),
00151                 segment->length() / 2 * middlePostionPercentage + segment->startOffset(),
00152                 center, segment->startColor(),
00153                 segment->endColor() );
00154         m_segments.insert( it, newSegment );
00155         segment->setStartOffset( center );
00156         segment->setMiddleOffset( segment->length() * middlePostionPercentage  + segment->startOffset() );
00157     }
00158 }
00159 
00160 void KisAutogradientResource::mirrorSegment( KisGradientSegment* segment )
00161 {
00162     Q_ASSERT(segment != 0);
00163     Color tmpColor = segment->startColor();
00164     segment->setStartColor( segment->endColor() );
00165     segment->setEndColor( tmpColor );
00166     segment->setMiddleOffset( segment->endOffset() - ( segment->middleOffset() - segment->startOffset() ) );
00167 
00168     if( segment->interpolation() == INTERP_SPHERE_INCREASING )
00169         segment->setInterpolation( INTERP_SPHERE_DECREASING );
00170     else if( segment->interpolation() == INTERP_SPHERE_DECREASING )
00171         segment->setInterpolation( INTERP_SPHERE_INCREASING );
00172 
00173     if( segment->colorInterpolation() == COLOR_INTERP_HSV_CW )
00174         segment->setColorInterpolation( COLOR_INTERP_HSV_CCW );
00175     else if( segment->colorInterpolation() == COLOR_INTERP_HSV_CCW )
00176         segment->setColorInterpolation( COLOR_INTERP_HSV_CW );
00177 }
00178 
00179 KisGradientSegment* KisAutogradientResource::removeSegment( KisGradientSegment* segment )
00180 {
00181     Q_ASSERT(segment != 0);
00182     if( m_segments.count() < 2 )
00183         return 0;
00184     QValueVector<KisGradientSegment*>::iterator it = qFind( m_segments.begin(), m_segments.end(), segment );
00185     if ( it != m_segments.end() )
00186     {
00187         double middlePostionPercentage;
00188         KisGradientSegment* nextSegment;
00189         if( it == m_segments.begin() )
00190         {
00191             nextSegment = (*(it+1));
00192             middlePostionPercentage = ( nextSegment->middleOffset() - nextSegment->startOffset() ) / nextSegment->length();
00193             nextSegment->setStartOffset( segment->startOffset() );
00194             nextSegment->setMiddleOffset( middlePostionPercentage * nextSegment->length() + nextSegment->startOffset() );
00195         }
00196         else
00197         {
00198             nextSegment = (*(it-1));
00199             middlePostionPercentage = ( nextSegment->middleOffset() - nextSegment->startOffset() ) / nextSegment->length();
00200             nextSegment->setEndOffset( segment->endOffset() );
00201             nextSegment->setMiddleOffset( middlePostionPercentage * nextSegment->length() + nextSegment->startOffset() );
00202         }
00203 
00204         delete segment;
00205         m_segments.erase( it );
00206         return nextSegment;
00207     }
00208     return 0;
00209 }
00210 
00211 bool KisAutogradientResource::removeSegmentPossible() const
00212 {
00213     if( m_segments.count() < 2 )
00214         return false;
00215     return true;
00216 }
00217 
00218 void KisAutogradientResource::updatePreview()
00219 {
00220     setImage( generatePreview( PREVIEW_WIDTH, PREVIEW_HEIGHT ) );
00221 }
KDE Home | KDE Accessibility Home | Description of Access Keys