33#include <tqfontmetrics.h>
45KCurve::KCurve(TQWidget *parent,
const char *name, WFlags f)
46 : TQWidget(parent, name, f)
49 m_readOnlyMode =
false;
50 m_guideVisible =
false;
54 setMouseTracking(
true);
55 setPaletteBackgroundColor(TQt::NoBackground);
56 setMinimumSize(150, 50);
57 TQPair<double,double> *p =
new TQPair<double,double>;
58 p->first = 0.0; p->second=0.0;
60 p =
new TQPair<double,double>;
61 p->first = 1.0; p->second=1.0;
63 m_points.setAutoDelete(
true);
64 setFocusPolicy(TQWidget::StrongFocus);
69 if (m_pix)
delete m_pix;
72void KCurve::reset(
void)
75 m_guideVisible =
false;
79void KCurve::setCurveGuide(TQColor color)
81 m_guideVisible =
true;
86void KCurve::setPixmap(TQPixmap pix)
88 if (m_pix)
delete m_pix;
89 m_pix =
new TQPixmap(pix);
93void KCurve::keyPressEvent(TQKeyEvent *e)
95 if(e->key() == TQt::Key_Delete || e->key() == TQt::Key_Backspace)
97 TQPair<double,double> *closest_point=NULL;
101 TQPair<double,double> *p = m_points.first();
102 double distance = 1000;
106 if (fabs (m_grab_point->first - p->first) < distance)
108 distance = fabs(m_grab_point->first - p->first);
113 m_points.remove(m_grab_point);
115 m_grab_point = closest_point;
119 TQWidget::keyPressEvent(e);
122void KCurve::paintEvent(TQPaintEvent *)
125 int wWidth = width();
126 int wHeight = height();
141 p1.scale(1.0*wWidth/m_pix->width(), 1.0*wHeight/m_pix->height());
142 p1.drawPixmap(0, 0, *m_pix);
149 p1.setPen(TQPen(TQt::gray, 1, TQt::SolidLine));
150 p1.drawLine(wWidth/3, 0, wWidth/3, wHeight);
151 p1.drawLine(2*wWidth/3, 0, 2*wWidth/3, wHeight);
152 p1.drawLine(0, wHeight/3, wWidth, wHeight/3);
153 p1.drawLine(0, 2*wHeight/3, wWidth, 2*wHeight/3);
156 double curvePrevVal = getCurveValue(0.0);
157 p1.setPen(TQPen(TQt::black, 1, TQt::SolidLine));
158 for (x = 0 ; x < wWidth ; x++)
163 curveX = (x + 0.5) / wWidth;
165 curveVal = getCurveValue(curveX);
167 p1.drawLine(x - 1, wHeight -
int(curvePrevVal * wHeight),
168 x, wHeight -
int(curveVal * wHeight));
170 curvePrevVal = curveVal;
172 p1.drawLine(x - 1, wHeight -
int(curvePrevVal * wHeight),
173 x, wHeight -
int(getCurveValue(1.0) * wHeight));
176 if ( !m_readOnlyMode )
178 TQPair<double,double> *p = m_points.first();
182 double curveX = p->first;
183 double curveY = p->second;
185 if(p == m_grab_point)
187 p1.setPen(TQPen(TQt::red, 3, TQt::SolidLine));
188 p1.drawEllipse(
int(curveX * wWidth) - 2,
189 wHeight - 2 -
int(curveY * wHeight), 4, 4 );
193 p1.setPen(TQPen(TQt::red, 1, TQt::SolidLine));
195 p1.drawEllipse(
int(curveX * wWidth) - 3,
196 wHeight - 3 -
int(curveY * wHeight), 6, 6 );
204 bitBlt(
this, 0, 0, &pm);
207void KCurve::mousePressEvent ( TQMouseEvent * e )
209 if (m_readOnlyMode)
return;
211 TQPair<double,double> *closest_point=NULL;
214 if (e->button() != TQt::LeftButton)
217 double x = e->pos().x() / (float)width();
218 double y = 1.0 - e->pos().y() / (float)height();
222 TQPair<double,double> *p = m_points.first();
223 int insert_pos,pos=0;
226 if (fabs (x - p->first) < distance)
228 distance = fabs(x - p->first);
233 insert_pos = pos + 1;
240 if(closest_point == NULL)
242 closest_point =
new TQPair<double,double>;
243 closest_point->first = x;
244 closest_point->second = y;
245 m_points.append(closest_point);
247 else if(distance * width() > 5)
249 closest_point =
new TQPair<double,double>;
250 closest_point->first = x;
251 closest_point->second = y;
252 m_points.insert(insert_pos, closest_point);
255 if(fabs(y - closest_point->second) * width() > 5)
259 m_grab_point = closest_point;
260 m_grabOffsetX = m_grab_point->first - x;
261 m_grabOffsetY = m_grab_point->second - y;
262 m_grab_point->first = x + m_grabOffsetX;
263 m_grab_point->second = y + m_grabOffsetY;
266 setCursor( KCursor::crossCursor() );
272 p = m_points.first();
275 if (p != m_grab_point)
277 if(p->first> m_leftmost && p->first < x)
278 m_leftmost = p->first;
279 if(p->first < m_rightmost && p->first > x)
280 m_rightmost = p->first;
287void KCurve::mouseReleaseEvent ( TQMouseEvent * e )
289 if (m_readOnlyMode)
return;
291 if (e->button() != TQt::LeftButton)
294 setCursor( KCursor::arrowCursor() );
300void KCurve::mouseMoveEvent ( TQMouseEvent * e )
302 if (m_readOnlyMode)
return;
304 double x = e->pos().x() / (float)width();
305 double y = 1.0 - e->pos().y() / (float)height();
307 if (m_dragging ==
false)
309 double distance = 1000;
310 double ydistance = 1000;
311 TQPair<double,double> *p = m_points.first();
314 if (fabs (x - p->first) < distance)
316 distance = fabs(x - p->first);
317 ydistance = fabs(y - p->second);
322 if (distance * width() > 5 || ydistance * height() > 5)
323 setCursor( KCursor::arrowCursor() );
325 setCursor( KCursor::crossCursor() );
329 setCursor( KCursor::crossCursor() );
335 x = m_leftmost + 1E-4;
338 x = m_rightmost - 1E-4;
346 m_grab_point->first = x;
347 m_grab_point->second = y;
355double KCurve::getCurveValue(
double x)
357 return getCurveValue(m_points, x);
360double KCurve::getCurveValue(TQPtrList<TQPair<double,double> > &curve,
double x)
363 TQPair<double,double> *p;
364 TQPair<double,double> *p0,*p1,*p2,*p3;
368 if(curve.count() == 0)
388 if((p0 = curve.prev()) == NULL)
389 p1 = p0 = curve.first();
394 if( (p = curve.next()) )
400 t = (x - p1->first) / (p2->first - p1->first);
401 c2 = (p2->second - p0->second) * (p2->first-p1->first) / (p2->first-p0->first);
403 c0 = -2*p2->second + 2*c3 + c2 + (p3->second - p1->second) * (p2->first - p1->first) / (p3->first - p1->first);
404 c1 = p2->second - c3 - c2 - c0;
405 val = ((c0*t + c1)*t + c2)*t + c3;
414TQPtrList<TQPair<double,double> > KCurve::getCurve()
416 TQPtrList<TQPair<double,double> > outlist;
417 TQPair<double,double> *p;
418 TQPair<double,double> *outpoint;
420 p = m_points.first();
423 outpoint =
new TQPair<double,double>(p->first, p->second);
424 outlist.append(outpoint);
430void KCurve::setCurve(TQPtrList<TQPair<double,double> >inlist)
432 TQPair<double,double> *p;
433 TQPair<double,double> *inpoint;
437 inpoint = inlist.first();
440 p =
new TQPair<double,double>(inpoint->first, inpoint->second);
442 inpoint = inlist.next();
446void KCurve::leaveEvent( TQEvent * )