chalk

kis_autogradient_resource.cpp
1/*
2 * Copyright (c) 2004 Cyrille Berger <cberger@cberger.net>
3 * 2004 Sven Langkamp <longamp@reallygood.de>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20#include "kis_gradient.h"
21#include "kis_autogradient_resource.h"
22
23// FIXME: use the same #define as in kis_gradient.cpp, probably best customizable?
24#define PREVIEW_WIDTH 64
25#define PREVIEW_HEIGHT 64
26
27
28void KisAutogradientResource::createSegment( int interpolation, int colorInterpolation, double startOffset, double endOffset, double middleOffset, TQColor left, TQColor right )
29{
30 pushSegment(new KisGradientSegment(interpolation, colorInterpolation, startOffset, middleOffset, endOffset, Color( left, 1 ), Color( right, 1 )));
31
32}
33
34const TQValueVector<double> KisAutogradientResource::getHandlePositions() const
35{
36 TQValueVector<double> handlePositions;
37
38 handlePositions.push_back(m_segments[0]->startOffset());
39 for (uint i = 0; i < m_segments.count(); i++)
40 {
41 handlePositions.push_back(m_segments[i]->endOffset());
42 }
43 return handlePositions;
44}
45
46const TQValueVector<double> KisAutogradientResource::getMiddleHandlePositions() const
47{
48 TQValueVector<double> middleHandlePositions;
49
50 for (uint i = 0; i < m_segments.count(); i++)
51 {
52 middleHandlePositions.push_back(m_segments[i]->middleOffset());
53 }
54 return middleHandlePositions;
55}
56
57void KisAutogradientResource::moveSegmentStartOffset( KisGradientSegment* segment, double t)
58{
59 TQValueVector<KisGradientSegment*>::iterator it = tqFind( m_segments.begin(), m_segments.end(), segment );
60 if ( it != m_segments.end() )
61 {
62 if ( it == m_segments.begin() )
63 {
64 segment->setStartOffset( 0.0 );
65 return;
66 }
67 KisGradientSegment* previousSegment = (*(it-1));
68 if ( t > segment->startOffset() )
69 {
70 if( t > segment->middleOffset() )
71 t = segment->middleOffset();
72 }
73 else {
74 if( t < previousSegment->middleOffset() )
75 t = previousSegment->middleOffset();
76 }
77 previousSegment->setEndOffset( t );
78 segment->setStartOffset( t );
79 }
80}
81
82void KisAutogradientResource::moveSegmentEndOffset( KisGradientSegment* segment, double t)
83{
84 TQValueVector<KisGradientSegment*>::iterator it = tqFind( m_segments.begin(), m_segments.end(), segment );
85 if ( it != m_segments.end() )
86 {
87 if ( it+1 == m_segments.end() )
88 {
89 segment->setEndOffset( 1.0 );
90 return;
91 }
92 KisGradientSegment* followingSegment = (*(it+1));
93 if ( t < segment->endOffset() )
94 {
95 if( t < segment->middleOffset() )
96 t = segment->middleOffset();
97 }
98 else {
99 if( t > followingSegment->middleOffset() )
100 t = followingSegment->middleOffset();
101 }
102 followingSegment->setStartOffset( t );
103 segment->setEndOffset( t );
104 }
105}
106
107void KisAutogradientResource::moveSegmentMiddleOffset( KisGradientSegment* segment, double t)
108{
109 if( segment )
110 {
111 if( t > segment->endOffset() )
112 segment->setMiddleOffset( segment->endOffset() );
113 else if( t < segment->startOffset() )
114 segment->setMiddleOffset( segment->startOffset() );
115 else
116 segment->setMiddleOffset( t );
117 }
118}
119
120void KisAutogradientResource::splitSegment( KisGradientSegment* segment )
121{
122 Q_ASSERT(segment != 0);
123 TQValueVector<KisGradientSegment*>::iterator it = tqFind( m_segments.begin(), m_segments.end(), segment );
124 if ( it != m_segments.end() )
125 {
126 KisGradientSegment* newSegment = new KisGradientSegment(
127 segment->interpolation(), segment->colorInterpolation(),
128 segment ->startOffset(),
129 ( segment->middleOffset() - segment->startOffset() ) / 2 + segment->startOffset(),
130 segment->middleOffset(),
131 segment->startColor(),
132 segment->colorAt( segment->middleOffset() ) );
133 m_segments.insert( it, newSegment );
134 segment->setStartColor( segment->colorAt( segment->middleOffset() ) );
135 segment->setStartOffset( segment->middleOffset() );
136 segment->setMiddleOffset( ( segment->endOffset() - segment->startOffset() ) / 2 + segment->startOffset() );
137 }
138}
139
140void KisAutogradientResource::duplicateSegment( KisGradientSegment* segment )
141{
142 Q_ASSERT(segment != 0);
143 TQValueVector<KisGradientSegment*>::iterator it = tqFind( m_segments.begin(), m_segments.end(), segment );
144 if ( it != m_segments.end() )
145 {
146 double middlePostionPercentage = ( segment->middleOffset() - segment->startOffset() ) / segment->length();
147 double center = segment->startOffset() + segment->length() / 2;
148 KisGradientSegment* newSegment = new KisGradientSegment(
149 segment->interpolation(), segment->colorInterpolation(),
150 segment ->startOffset(),
151 segment->length() / 2 * middlePostionPercentage + segment->startOffset(),
152 center, segment->startColor(),
153 segment->endColor() );
154 m_segments.insert( it, newSegment );
155 segment->setStartOffset( center );
156 segment->setMiddleOffset( segment->length() * middlePostionPercentage + segment->startOffset() );
157 }
158}
159
160void KisAutogradientResource::mirrorSegment( KisGradientSegment* segment )
161{
162 Q_ASSERT(segment != 0);
163 Color tmpColor = segment->startColor();
164 segment->setStartColor( segment->endColor() );
165 segment->setEndColor( tmpColor );
166 segment->setMiddleOffset( segment->endOffset() - ( segment->middleOffset() - segment->startOffset() ) );
167
168 if( segment->interpolation() == INTERP_SPHERE_INCREASING )
169 segment->setInterpolation( INTERP_SPHERE_DECREASING );
170 else if( segment->interpolation() == INTERP_SPHERE_DECREASING )
171 segment->setInterpolation( INTERP_SPHERE_INCREASING );
172
173 if( segment->colorInterpolation() == COLOR_INTERP_HSV_CW )
174 segment->setColorInterpolation( COLOR_INTERP_HSV_CCW );
175 else if( segment->colorInterpolation() == COLOR_INTERP_HSV_CCW )
176 segment->setColorInterpolation( COLOR_INTERP_HSV_CW );
177}
178
179KisGradientSegment* KisAutogradientResource::removeSegment( KisGradientSegment* segment )
180{
181 Q_ASSERT(segment != 0);
182 if( m_segments.count() < 2 )
183 return 0;
184 TQValueVector<KisGradientSegment*>::iterator it = tqFind( m_segments.begin(), m_segments.end(), segment );
185 if ( it != m_segments.end() )
186 {
187 double middlePostionPercentage;
188 KisGradientSegment* nextSegment;
189 if( it == m_segments.begin() )
190 {
191 nextSegment = (*(it+1));
192 middlePostionPercentage = ( nextSegment->middleOffset() - nextSegment->startOffset() ) / nextSegment->length();
193 nextSegment->setStartOffset( segment->startOffset() );
194 nextSegment->setMiddleOffset( middlePostionPercentage * nextSegment->length() + nextSegment->startOffset() );
195 }
196 else
197 {
198 nextSegment = (*(it-1));
199 middlePostionPercentage = ( nextSegment->middleOffset() - nextSegment->startOffset() ) / nextSegment->length();
200 nextSegment->setEndOffset( segment->endOffset() );
201 nextSegment->setMiddleOffset( middlePostionPercentage * nextSegment->length() + nextSegment->startOffset() );
202 }
203
204 delete segment;
205 m_segments.erase( it );
206 return nextSegment;
207 }
208 return 0;
209}
210
211bool KisAutogradientResource::removeSegmentPossible() const
212{
213 if( m_segments.count() < 2 )
214 return false;
215 return true;
216}
217
218void KisAutogradientResource::updatePreview()
219{
220 setImage( generatePreview( PREVIEW_WIDTH, PREVIEW_HEIGHT ) );
221}