kiss_fft/_kiss_fft_guts.h
kiss_fft/kiss_fft.c
kiss_fft/tools/kiss_fftr.c
- beziercurve/cubicbezierspline.cpp
beziercurve/beziersplineeditor.cpp
beziercurve/beziersplinewidget.cpp
+ beziercurve/bpoint.cpp
+ beziercurve/cubicbezierspline.cpp
)
add_definitions(${KDE4_DEFINITIONS})
m_spline.setPoint(m_currentPointIndex, p);
// during validation the point might have changed
emit currentPoint(m_spline.points()[m_currentPointIndex]);
+ emit modified();
update();
}
}
case PTypeH1:
rightX = point.p.x();
if (m_currentPointIndex == 0)
- leftX = -1000;
+ leftX = -4;
else
leftX = m_spline.points()[m_currentPointIndex - 1].p.x();
x = qBound(leftX, x, rightX);
- point.h1 = QPointF(x, y);
+ point.setH1(QPointF(x, y));
break;
case PTypeP:
// try to restore
point.h1 = m_grabPOriginal.h1;
point.h2 = m_grabPOriginal.h2;
- // and then move them by same offset
+ // and move by same offset
+ // (using update handle in point.setP won't work because the offset between new and old point is very small)
point.h1 += QPointF(x, y) - m_grabPOriginal.p;
point.h2 += QPointF(x, y) - m_grabPOriginal.p;
- point.p = QPointF(x, y);
+ point.setP(QPointF(x, y), false);
break;
case PTypeH2:
leftX = point.p.x();
if (m_currentPointIndex == m_spline.points().count() - 1)
- rightX = 1001;
+ rightX = 5;
else
rightX = m_spline.points()[m_currentPointIndex + 1].p.x();
x = qBound(leftX, x, rightX);
- point.h2 = QPointF(x, y);
+ point.setH2(QPointF(x, y));
};
int index = m_currentPointIndex;
layout->addWidget(widget);
m_ui.buttonLinkHandles->setIcon(KIcon("insert-link"));
- m_ui.buttonLinkHandles->setEnabled(false);
m_ui.buttonZoomIn->setIcon(KIcon("zoom-in"));
m_ui.buttonZoomOut->setIcon(KIcon("zoom-out"));
m_ui.buttonGridChange->setIcon(KIcon("view-grid"));
connect(&m_edit, SIGNAL(modified()), this, SIGNAL(modified()));
connect(&m_edit, SIGNAL(currentPoint(const BPoint&)), this, SLOT(slotUpdatePoint(const BPoint&)));
- connect(m_ui.spinPX, SIGNAL(editingFinished()), this, SLOT(slotUpdateSpline()));
- connect(m_ui.spinPY, SIGNAL(editingFinished()), this, SLOT(slotUpdateSpline()));
- connect(m_ui.spinH1X, SIGNAL(editingFinished()), this, SLOT(slotUpdateSpline()));
- connect(m_ui.spinH1Y, SIGNAL(editingFinished()), this, SLOT(slotUpdateSpline()));
- connect(m_ui.spinH2X, SIGNAL(editingFinished()), this, SLOT(slotUpdateSpline()));
- connect(m_ui.spinH2Y, SIGNAL(editingFinished()), this, SLOT(slotUpdateSpline()));
+ connect(m_ui.spinPX, SIGNAL(editingFinished()), this, SLOT(slotUpdatePointP()));
+ connect(m_ui.spinPY, SIGNAL(editingFinished()), this, SLOT(slotUpdatePointP()));
+ connect(m_ui.spinH1X, SIGNAL(editingFinished()), this, SLOT(slotUpdatePointH1()));
+ connect(m_ui.spinH1Y, SIGNAL(editingFinished()), this, SLOT(slotUpdatePointH1()));
+ connect(m_ui.spinH2X, SIGNAL(editingFinished()), this, SLOT(slotUpdatePointH2()));
+ connect(m_ui.spinH2Y, SIGNAL(editingFinished()), this, SLOT(slotUpdatePointH2()));
+ connect(m_ui.buttonLinkHandles, SIGNAL(toggled(bool)), this, SLOT(slotSetHandlesLinked(bool)));
connect(m_ui.buttonZoomIn, SIGNAL(clicked()), &m_edit, SLOT(slotZoomIn()));
connect(m_ui.buttonZoomOut, SIGNAL(clicked()), &m_edit, SLOT(slotZoomOut()));
connect(m_ui.buttonGridChange, SIGNAL(clicked()), this, SLOT(slotGridChange()));
m_ui.spinH1Y->setValue(qRound(p.h1.y() * 255));
m_ui.spinH2X->setValue(qRound(p.h2.x() * 255));
m_ui.spinH2Y->setValue(qRound(p.h2.y() * 255));
+ m_ui.buttonLinkHandles->setChecked(p.handlesLinked);
}
blockSignals(false);
}
-void BezierSplineWidget::slotUpdateSpline()
+void BezierSplineWidget::slotUpdatePointP()
{
BPoint p = m_edit.getCurrentPoint();
- // check for every value, so we do not lose too much info through rounding
- if (m_ui.spinPX->value() != qRound(p.p.x() * 255))
- p.p.setX(m_ui.spinPX->value() / 255.);
- if (m_ui.spinPY->value() != qRound(p.p.y() * 255))
- p.p.setY(m_ui.spinPY->value() / 255.);
+ p.setP(QPointF(m_ui.spinPX->value() / 255., m_ui.spinPY->value() / 255.));
- if (m_ui.spinH1X->value() != qRound(p.h1.x() * 255))
- p.h1.setX(m_ui.spinH1X->value() / 255.);
- if (m_ui.spinH1Y->value() != qRound(p.h1.y() * 255))
- p.h1.setY(m_ui.spinH1Y->value() / 255.);
+ m_edit.updateCurrentPoint(p);
+}
+
+void BezierSplineWidget::slotUpdatePointH1()
+{
+ BPoint p = m_edit.getCurrentPoint();
- if (m_ui.spinH2X->value() != qRound(p.h2.x() * 255))
- p.h2.setX(m_ui.spinH2X->value() / 255.);
- if (m_ui.spinH2Y->value() != qRound(p.h2.y() * 255))
- p.h2.setY(m_ui.spinH2Y->value() / 255.);
+ p.setH1(QPointF(m_ui.spinH1X->value() / 255., m_ui.spinH1Y->value() / 255.));
m_edit.updateCurrentPoint(p);
- emit modified();
+}
+
+void BezierSplineWidget::slotUpdatePointH2()
+{
+ BPoint p = m_edit.getCurrentPoint();
+
+ p.setH2(QPointF(m_ui.spinH2X->value() / 255., m_ui.spinH2Y->value() / 255.));
+
+ m_edit.updateCurrentPoint(p);
+}
+
+void BezierSplineWidget::slotSetHandlesLinked(bool linked)
+{
+ BPoint p = m_edit.getCurrentPoint();
+ p.handlesLinked = linked;
+ m_edit.updateCurrentPoint(p);
}
void BezierSplineWidget::slotResetSpline()
private slots:
void slotUpdatePoint(const BPoint &p);
- void slotUpdateSpline();
+
+ void slotUpdatePointP();
+ void slotUpdatePointH1();
+ void slotUpdatePointH2();
+
void slotGridChange();
void slotShowPixmap(bool show = true);
void slotResetSpline();
+ void slotSetHandlesLinked(bool linked);
private:
Ui::BezierSpline_UI m_ui;
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Till Theato (root@ttill.de) *
+ * This file is part of Kdenlive (www.kdenlive.org). *
+ * *
+ * Kdenlive is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * Kdenlive is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#include "bpoint.h"
+
+
+BPoint::BPoint() :
+ h1(QPointF(-1, -1)),
+ p(QPointF(-1, -1)),
+ h2(QPointF(-1, -1)),
+ handlesLinked(true)
+{
+}
+
+BPoint::BPoint(QPointF handle1, QPointF point, QPointF handle2) :
+ h1(handle1),
+ p(point),
+ h2(handle2)
+{
+ autoSetLinked();
+}
+
+bool BPoint::operator==(const BPoint& point) const
+{
+ return point.h1 == h1 &&
+ point.p == p &&
+ point.h2 == h2;
+}
+
+void BPoint::setP(QPointF point, bool updateHandles)
+{
+ QPointF offset = point - p;
+ p = point;
+ if (updateHandles) {
+ h1 += offset;
+ h2 += offset;
+ }
+}
+
+void BPoint::setH1(QPointF handle1)
+{
+ h1 = handle1;
+ if (handlesLinked) {
+ qreal angle = QLineF(h1, p).angle();
+ QLineF l = QLineF(p, h2);
+ l.setAngle(angle);
+ h2 = l.p2();
+ }
+}
+
+void BPoint::setH2(QPointF handle2)
+{
+ h2 = handle2;
+ if (handlesLinked) {
+ qreal angle = QLineF(h2, p).angle();
+ QLineF l = QLineF(p, h1);
+ l.setAngle(angle);
+ h1 = l.p2();
+ }
+}
+
+void BPoint::keepInRange(qreal xMin, qreal xMax)
+{
+}
+
+void BPoint::autoSetLinked()
+{
+ handlesLinked = !QLineF(h1, p).angleTo(QLineF(p, h2));
+}
--- /dev/null
+/***************************************************************************
+ * Copyright (C) 2011 by Till Theato (root@ttill.de) *
+ * This file is part of Kdenlive (www.kdenlive.org). *
+ * *
+ * Kdenlive is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation, either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * Kdenlive is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with Kdenlive. If not, see <http://www.gnu.org/licenses/>. *
+ ***************************************************************************/
+
+#ifndef BPOINT_H
+#define BPOINT_H
+
+#include <QtCore>
+
+/**
+ * @brief Represents a point in a cubic Bézier spline.
+ */
+
+class BPoint
+{
+public:
+ /** @brief Sets the point to -1, -1 to mark it as unusable (until point + handles have proper values) */
+ BPoint();
+ /** @brief Sets up according to the params. Linking detecting is done using autoSetLinked(). */
+ BPoint(QPointF handle1, QPointF point, QPointF handle2);
+
+ bool operator==(const BPoint &point) const;
+
+ /** @brief Sets p to @param point.
+ * @param updateHandles (default = true) Whether to make sure the handles keep their position relative to p. */
+ void setP(QPointF point, bool updateHandles = true);
+
+ /** @brief Sets h1 to @param handle1.
+ *
+ * If handlesLinked is true h2 is updated. */
+ void setH1(QPointF handle1);
+
+ /** @brief Sets h2 to @param handle2.
+ *
+ * If handlesLinked is true h1 is updated. */
+ void setH2(QPointF handle2);
+ void keepInRange(qreal xMin, qreal xMax);
+
+ /** @brief Sets handlesLinked to true if the handles are in a linked state (line through h1, p, h2) otherwise to false. */
+ void autoSetLinked();
+
+ /** handle 1 */
+ QPointF h1;
+ /** point */
+ QPointF p;
+ /** handle 2 */
+ QPointF h2;
+
+ /** handles are locked to achieve a natural locking spline => PH1 = -r*PH2 ; a line can be drawn through h1, p, h2 */
+ bool handlesLinked;
+};
+
+#endif
#include "cubicbezierspline.h"
-#include <KDebug>
/** @brief For sorting a Bezier spline. Whether a is before b. */
static bool pointLessThan(const BPoint &a, const BPoint &b)
m_validSpline(false),
m_precision(100)
{
- BPoint start;
- start.p.setX(0);
- start.p.setY(0);
- start.h1.setX(0);
- start.h1.setY(0);
- start.h2.setX(0.1);
- start.h2.setY(0.1);
- m_points.append(start);
-
- BPoint end;
- end.p.setX(1);
- end.p.setY(1);
- end.h1.setX(0.9);
- end.h1.setY(0.9);
- end.h2.setX(1);
- end.h2.setY(1);
- m_points.append(end);
+ m_points.append(BPoint(QPointF(0, 0), QPointF(0, 0), QPointF(.1, .1)));
+ m_points.append(BPoint(QPointF(.9, .9), QPointF(1, 1), QPointF(1, 1)));
}
CubicBezierSpline::CubicBezierSpline(const CubicBezierSpline& spline, QObject* parent) :
values.append(QPointF(xy.at(0).toDouble(), xy.at(1).toDouble()));
}
if (values.count() == 3) {
- BPoint bp;
- bp.h1 = values.at(0);
- bp.p = values.at(1);
- bp.h2 = values.at(2);
- m_points.append(bp);
+ m_points.append(BPoint(values.at(0), values.at(1), values.at(2)));
}
}
#ifndef CUBICBEZIERSPLINE_H
#define CUBICBEZIERSPLINE_H
+#include "bpoint.h"
#include <QtCore>
-class BPoint
-{
-public:
- QPointF h1; // handle 1
- QPointF p; // point
- QPointF h2; // handle 2
-
- BPoint() { p = QPointF(-1,-1); } // makes it illegal -> cannot be equal any point
- bool operator==(const BPoint &point) const { return point.h1 == h1 && point.p == p && point.h2 == h2; }
-};
class CubicBezierSpline : public QObject
{
<rect>
<x>0</x>
<y>0</y>
- <width>315</width>
- <height>83</height>
+ <width>351</width>
+ <height>78</height>
</rect>
</property>
<property name="windowTitle">
<property name="margin">
<number>0</number>
</property>
+ <property name="spacing">
+ <number>0</number>
+ </property>
<item row="0" column="0" colspan="9">
<widget class="QWidget" name="widget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item row="1" column="4">
<widget class="QToolButton" name="buttonLinkHandles">
<property name="toolTip">
- <string>Link the Handles' position so you draw a line through Handle -> Point -> Handle.<br />Results in a natural spline.</string>
+ <string>Link the handles' position.<br />Results in a natural spline.</string>
</property>
<property name="text">
<string>...</string>