aboutsummaryrefslogtreecommitdiff
path: root/tools/CurveEditor/source/Internal/Window
diff options
context:
space:
mode:
authorBryan Galdrikian <[email protected]>2017-02-24 09:32:20 -0800
committerBryan Galdrikian <[email protected]>2017-02-24 09:32:20 -0800
commite1bf674c16e3c8472b29574159c789cd3f0c64e0 (patch)
tree9f0cfce09c71a2c27ff19589fcad6cd83504477c /tools/CurveEditor/source/Internal/Window
parentfirst commit (diff)
downloadblast-e1bf674c16e3c8472b29574159c789cd3f0c64e0.tar.xz
blast-e1bf674c16e3c8472b29574159c789cd3f0c64e0.zip
Updating to [email protected] and [email protected] with a new directory structure.
NvBlast folder is gone, files have been moved to top level directory. README is changed to reflect this.
Diffstat (limited to 'tools/CurveEditor/source/Internal/Window')
-rw-r--r--tools/CurveEditor/source/Internal/Window/AlphaDialog.cpp181
-rw-r--r--tools/CurveEditor/source/Internal/Window/AlphaDialog.h47
-rw-r--r--tools/CurveEditor/source/Internal/Window/ColorWidget.cpp1724
-rw-r--r--tools/CurveEditor/source/Internal/Window/ColorWidget.h126
-rw-r--r--tools/CurveEditor/source/Internal/Window/CurveEditorMainWindow.cpp1530
-rw-r--r--tools/CurveEditor/source/Internal/Window/CurveWidget.cpp1229
-rw-r--r--tools/CurveEditor/source/Internal/Window/CurveWidget.h158
7 files changed, 4995 insertions, 0 deletions
diff --git a/tools/CurveEditor/source/Internal/Window/AlphaDialog.cpp b/tools/CurveEditor/source/Internal/Window/AlphaDialog.cpp
new file mode 100644
index 0000000..a51a802
--- /dev/null
+++ b/tools/CurveEditor/source/Internal/Window/AlphaDialog.cpp
@@ -0,0 +1,181 @@
+#include "AlphaDialog.h"
+#include "ui_AlphaDialog.h"
+#include <QtGui/QPaintEvent>
+#include <QtGui/QPainter>
+#include <QtGui/QPainterPath>
+
+namespace nvidia {
+namespace CurveEditor {
+
+const int MARGIN_X = 8;
+const int MARGIN_Y = 8;
+
+const int ALPHA_W = 255;
+const int ALPHA_H = 30;
+
+const int CURSOR_W = 12;
+const int CURSOR_H = 12;
+
+static QImage s_triangleUp;
+
+void InitTriangleResources(int w, int h)
+{
+ s_triangleUp = QImage(w, h, QImage::Format_ARGB32);
+ s_triangleUp.fill(QColor(0, 0, 0, 0));
+
+ // a painter cannot switch device?
+ QPainterPath path;
+ QPainter painter(&s_triangleUp);
+ painter.setRenderHint(QPainter::Antialiasing,true);
+ path = QPainterPath(); // trick to clear up a path
+ path.moveTo(w>>1, 0);
+ path.lineTo(0, h);
+ path.lineTo(w, h);
+ path.lineTo(w>>1, 0);
+ painter.setPen(Qt::NoPen);
+ painter.fillPath(path, QBrush(QColor(50, 50, 50)));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool isClickedInCursor(const QPoint& cursorPos, const QPoint& p)
+{
+ QVector<QPoint> points;
+ points.push_back(cursorPos);
+ points.push_back(QPoint(cursorPos.x() - (CURSOR_W>>1), cursorPos.y() + CURSOR_H));
+ points.push_back(QPoint(cursorPos.x() + (CURSOR_W>>1), cursorPos.y() + CURSOR_H));
+ points.push_back(cursorPos);
+
+ QPolygon polygon(points);
+ return polygon.containsPoint(p, Qt::OddEvenFill);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+ int AlphaDialog::getAlpha(int alpha, QWidget *parent)
+ {
+ AlphaDialog dlg(parent, alpha);
+ dlg.exec();
+ return dlg._alpha;
+ }
+
+//////////////////////////////////////////////////////////////////////////////
+AlphaDialog::AlphaDialog(QWidget *parent, int alpha) :
+ QDialog(parent),
+ ui(new Ui::AlphaDialog),
+ _drag(false),
+ _alpha(alpha),
+ _xOffset(0)
+{
+ ui->setupUi(this);
+ setWindowFlags(windowFlags()&~Qt::WindowContextHelpButtonHint);
+ setFixedWidth(271);
+ setFixedHeight(120);
+
+ ui->spinBoxAlpha->setValue(_alpha);
+
+ InitTriangleResources(12, 12);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+AlphaDialog::~AlphaDialog()
+{
+ delete ui;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void AlphaDialog::paintEvent(QPaintEvent * e)
+{
+ QDialog::paintEvent(e);
+
+ QPainter painter;
+ painter.begin(this);
+ drawAlphaRectangle(painter);
+ drawCursor(painter, _alpha + MARGIN_X);
+ painter.end();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void AlphaDialog::mousePressEvent( QMouseEvent* e )
+{
+ if(e->button() & Qt::LeftButton)
+ {
+ QPoint mousePos = e->pos();
+
+ if (isClickedInCursor(QPoint(_alpha + MARGIN_X, MARGIN_Y + ALPHA_H), mousePos))
+ {
+ _xOffset = _alpha + MARGIN_X - mousePos.x();
+ _drag = true;
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void AlphaDialog::mouseReleaseEvent( QMouseEvent* e )
+{
+ _drag = false;
+ _xOffset = -1;
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void AlphaDialog::mouseMoveEvent( QMouseEvent* e )
+{
+ Qt::MouseButtons buttons = e->buttons();
+
+ if(buttons & Qt::LeftButton)
+ {
+ if (_drag)
+ {
+ QPoint mousePos = e->pos();
+
+ _alpha = mousePos.x() + _xOffset - MARGIN_X;
+ if (_alpha < 0)
+ {
+ _alpha = 0;
+ }
+ else if(_alpha > ALPHA_W)
+ {
+ _alpha = ALPHA_W;
+ }
+ ui->spinBoxAlpha->setValue(_alpha);
+ update();
+ }
+ }
+}
+
+void AlphaDialog::drawAlphaRectangle(QPainter& painter)
+{
+ QPointF topLeftPnt(MARGIN_X, MARGIN_Y);
+ QPointF topRightPnt(MARGIN_X + ALPHA_W, MARGIN_Y);
+ QPointF bottomRightPnt(MARGIN_X + ALPHA_W, MARGIN_Y + ALPHA_H);
+ QPointF bottomLeftPnt(MARGIN_X, MARGIN_Y + ALPHA_H);
+ QPainterPath path;
+ path.moveTo(topLeftPnt);
+ path.lineTo(topRightPnt);
+ path.lineTo(bottomRightPnt);
+ path.lineTo(bottomLeftPnt);
+
+ QColor colorLeft(0, 0, 0, 255);
+ QColor colorRight(255, 255, 255, 255);
+ colorLeft.setAlpha(255);
+ colorRight.setAlpha(255);
+ QLinearGradient indicatorGradient(topLeftPnt,topRightPnt);
+ indicatorGradient.setColorAt(0.0, colorLeft);
+ indicatorGradient.setColorAt(1.0, colorRight);
+
+ painter.fillPath(path, indicatorGradient);
+}
+
+void AlphaDialog::drawCursor(QPainter& painter, int xPos)
+{
+ QRect rect(xPos - (CURSOR_W>>1), MARGIN_Y + ALPHA_H, CURSOR_W, CURSOR_H);
+ painter.drawImage(rect, s_triangleUp);
+
+}
+
+void AlphaDialog::on_spinBoxAlpha_valueChanged(int arg1)
+{
+ _alpha = arg1;
+}
+
+} // namespace CurveEditor
+} // namespace nvidia \ No newline at end of file
diff --git a/tools/CurveEditor/source/Internal/Window/AlphaDialog.h b/tools/CurveEditor/source/Internal/Window/AlphaDialog.h
new file mode 100644
index 0000000..985d0b4
--- /dev/null
+++ b/tools/CurveEditor/source/Internal/Window/AlphaDialog.h
@@ -0,0 +1,47 @@
+#ifndef ALPHADIALOG_H
+#define ALPHADIALOG_H
+
+#include <QtWidgets/QDialog>
+
+namespace Ui {
+ class AlphaDialog;
+}
+
+namespace nvidia {
+namespace CurveEditor {
+
+class AlphaDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ static int getAlpha(int alpha = 255, QWidget *parent = 0);
+
+ explicit AlphaDialog(QWidget *parent = 0, int alpha = 255);
+ ~AlphaDialog();
+
+protected:
+ // QWidget events
+ virtual void paintEvent(QPaintEvent * e);
+
+ virtual void mousePressEvent(QMouseEvent* e);
+ virtual void mouseReleaseEvent(QMouseEvent* e);
+ virtual void mouseMoveEvent(QMouseEvent* e);
+private slots:
+ void on_spinBoxAlpha_valueChanged(int arg1);
+
+private:
+ void drawAlphaRectangle(QPainter& painter);
+ void drawCursor(QPainter& painter, int xPos);
+
+private:
+ Ui::AlphaDialog *ui;
+ bool _drag;
+ int _alpha;
+ int _xOffset;
+};
+
+} // namespace CurveEditor
+} // namespace nvidia
+
+#endif // ALPHADIALOG_H
diff --git a/tools/CurveEditor/source/Internal/Window/ColorWidget.cpp b/tools/CurveEditor/source/Internal/Window/ColorWidget.cpp
new file mode 100644
index 0000000..a84ee70
--- /dev/null
+++ b/tools/CurveEditor/source/Internal/Window/ColorWidget.cpp
@@ -0,0 +1,1724 @@
+#include "ColorWidget.h"
+#include <QtGui/QPaintEvent>
+#include <QtGui/QPainter>
+#include <QtGui/QPainterPath>
+#include <QtGui/QImage>
+#include <assert.h>
+#include <QtCore/QDebug>
+#include <QtCore/QTime>
+#include <QtWidgets/QToolTip>
+#include "CurveEditorMainWindow.h"
+
+namespace nvidia {
+namespace CurveEditor {
+
+const int MARGIN_X = 8;
+const int MARGIN_Y = 4;
+const int CONTROL_POINT_CURSOR_W = 12;
+const int CONTROL_POINT_CURSOR_H = 12;
+const int WEIGHT_CURSOR_W = 6;
+const int WEIGHT_CURSOR_H = 6;
+const int SPACING_V = 0;
+
+static QImage S_CtrlPntWithTexCursorNormalImg;
+static QImage S_CtrlPntWithTexCursorPickedImg;
+static QImage S_WeightCursorNormalImg;
+static QImage S_WeightCursorPickedImg;
+
+#define ROUND(v) (int(v + 0.5))
+
+class TimeConsumeTracker
+{
+public:
+ TimeConsumeTracker(QString text)
+ : _text(text)
+ {
+ _time.start();
+ }
+
+ ~TimeConsumeTracker()
+ {
+ qDebug()<<_text<<" consume: "<<_time.elapsed();
+ }
+
+ QTime _time;
+ QString _text;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+void InitCursorResources()
+{
+ int w = CONTROL_POINT_CURSOR_W;
+ int h = CONTROL_POINT_CURSOR_H;
+ S_CtrlPntWithTexCursorNormalImg = QImage(w, h, QImage::Format_ARGB32);
+ S_CtrlPntWithTexCursorPickedImg = QImage(w, h, QImage::Format_ARGB32);
+ S_CtrlPntWithTexCursorNormalImg.fill(QColor(0, 0, 0, 0));
+ S_CtrlPntWithTexCursorPickedImg.fill(QColor(0, 0, 0, 0));
+
+ ///////////////////////////////////////////////////////////////////////////
+ QPainter painter(&S_CtrlPntWithTexCursorNormalImg);
+ painter.setRenderHint(QPainter::Antialiasing, true);
+ QPainterPath path; // trick to clear up a path
+ path.moveTo(w >> 1, 0);
+ path.lineTo(w >> 2, h >> 2);
+ path.lineTo(w >> 1, h >> 1);
+ path.lineTo((w >> 1) + (w >> 2), h >> 2);
+ path.lineTo(w >> 1, 0);
+ painter.setPen(Qt::NoPen);
+ painter.fillPath(path, QBrush(QColor(255, 255, 255)));
+
+ path = QPainterPath(); // trick to clear up a path
+ path.moveTo(w >> 2, h >> 2);
+ path.lineTo(0, h >> 1);
+ path.lineTo(w >> 2, (h >> 1) + (h >> 2));
+ path.lineTo(w >> 1, h >> 1);
+ path.lineTo(w >> 2, h >> 2);
+ painter.setPen(Qt::NoPen);
+ painter.fillPath(path, (QColor(0, 0, 0)));
+
+ path = QPainterPath(); // trick to clear up a path
+ path.moveTo(w >> 1, h >> 1);
+ path.lineTo(w >> 2, (h >> 1) + (h >> 2));
+ path.lineTo(w >> 1, h);
+ path.lineTo((w >> 1) + (w >> 2), (h >> 1) + (h >> 2));
+ path.lineTo(w >> 1, h >> 1);
+ painter.setPen(Qt::NoPen);
+ painter.fillPath(path, QBrush(QColor(255, 255, 255)));
+
+ path = QPainterPath(); // trick to clear up a path
+ path.moveTo((w >> 1) + (w >> 2), h >> 2);
+ path.lineTo(w >> 1, h >> 1);
+ path.lineTo((w >> 1) + (w >> 2), (h >> 1) + (h >> 2));
+ path.lineTo(w, h >> 1);
+ path.lineTo((w >> 1) + (w >> 2), h >> 2);
+ painter.setPen(Qt::NoPen);
+ painter.fillPath(path, (QColor(0, 0, 0)));
+
+ path = QPainterPath(); // trick to clear up a path
+ path.moveTo(w >> 1, 0);
+ path.lineTo(0, h >> 1);
+ path.lineTo(w >> 1, h);
+ path.lineTo(w, h >> 1);
+ path.lineTo(w >> 1, 0);
+ painter.setPen(QPen(Qt::white, 1, Qt::SolidLine));
+ painter.drawPath(path);
+
+ ///////////////////////////////////////////////////////////////////////////
+ // a painter cannot switch device?
+ QPainter painter2(&S_CtrlPntWithTexCursorPickedImg);
+ painter2.setRenderHint(QPainter::Antialiasing,true);
+ path = QPainterPath(); // trick to clear up a path
+ path.moveTo(w>>1, 0);
+ path.lineTo(w>>2, h>>2);
+ path.lineTo(w>>1, h>>1);
+ path.lineTo((w>>1)+(w>>2), h>>2);
+ path.lineTo(w>>1, 0);
+ painter2.setPen(Qt::NoPen);
+ painter2.fillPath(path, QBrush(QColor(255, 255, 255)));
+
+ path = QPainterPath(); // trick to clear up a path
+ path.moveTo(w>>2, h>>2);
+ path.lineTo(0, h>>1);
+ path.lineTo(w>>2, (h>>1)+(h>>2));
+ path.lineTo(w>>1, h>>1);
+ path.lineTo(w>>2, h>>2);
+ painter2.setPen(Qt::NoPen);
+ painter2.fillPath(path, (QColor(0, 0, 0)));
+
+ path = QPainterPath(); // trick to clear up a path
+ path.moveTo(w>>1, h>>1);
+ path.lineTo(w>>2, (h>>1)+(h>>2));
+ path.lineTo(w>>1, h);
+ path.lineTo((w>>1)+(w>>2), (h>>1)+(h>>2));
+ path.lineTo(w>>1, h>>1);
+ painter2.setPen(Qt::NoPen);
+ painter2.fillPath(path, QBrush(QColor(255, 255, 255)));
+
+ path = QPainterPath(); // trick to clear up a path
+ path.moveTo((w>>1)+(w>>2), h>>2);
+ path.lineTo(w>>1, h>>1);
+ path.lineTo((w>>1)+(w>>2), (h>>1)+(h>>2));
+ path.lineTo(w, h>>1);
+ path.lineTo((w>>1)+(w>>2), h>>2);
+ painter2.setPen(Qt::NoPen);
+ painter2.fillPath(path, (QColor(0, 0, 0)));
+
+ path = QPainterPath(); // trick to clear up a path
+ path.moveTo(w>>1, 0);
+ path.lineTo(0, h>>1);
+ path.lineTo(w>>1, h);
+ path.lineTo(w, h>>1);
+ path.lineTo(w>>1, 0);
+ painter2.setPen(QPen(Qt::green,1, Qt::SolidLine));
+ painter2.drawPath(path);
+
+ ///////////////////////////////////////////////////////////////////////////
+ w = WEIGHT_CURSOR_W;
+ h = WEIGHT_CURSOR_H;
+ S_WeightCursorNormalImg = QImage(w, h, QImage::Format_ARGB32);
+ S_WeightCursorPickedImg = QImage(w, h, QImage::Format_ARGB32);
+ S_WeightCursorNormalImg.fill(QColor(0, 0, 0, 0));
+ S_WeightCursorPickedImg.fill(QColor(0, 0, 0, 0));
+ ///////////////////////////////////////////////////////////////////////////
+ QPainter painter3(&S_WeightCursorNormalImg);
+ painter3.setRenderHints(QPainter::Antialiasing,true);
+
+ path = QPainterPath(); // trick to clear up a path
+ path.moveTo(w>>1, 0);
+ path.lineTo(0, h>>1);
+ path.lineTo(w>>1, h);
+ path.lineTo(w, h>>1);
+ path.lineTo(w>>1, 0);
+ painter3.setPen(QPen(Qt::black, 1, Qt::SolidLine));
+ painter3.drawPath(path);
+ painter3.fillPath(path, QBrush(QColor(255, 255, 255)));
+
+ ///////////////////////////////////////////////////////////////////////////
+ QPainter painter4(&S_WeightCursorPickedImg);
+ painter4.setRenderHints(QPainter::Antialiasing,true);
+
+ path = QPainterPath(); // trick to clear up a path
+ path.moveTo(w>>1, 0);
+ path.lineTo(0, h>>1);
+ path.lineTo(w>>1, h);
+ path.lineTo(w, h>>1);
+ path.lineTo(w>>1, 0);
+ painter4.setPen(QPen(Qt::black, 1, Qt::SolidLine));
+ painter4.drawPath(path);
+ painter4.fillPath(path, QBrush(QColor(0, 0, 0)));
+}
+
+//////////////////////////////////////////////////////////////////////////////
+float NDCToScreenCoord(QWidget* pWidget, float xValueOfUnitInterval)
+{
+ int w = pWidget->width();
+ return MARGIN_X + (w - MARGIN_X * 2.0) * xValueOfUnitInterval;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+float _screenToNDC(QWidget* pWidget, int xPos)
+{
+ int w = pWidget->width();
+ return ((float)(xPos - MARGIN_X)) / (w - MARGIN_X * 2.0f);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool isClickedInCtrlPntCursor(const QPointF& cursorPos, const QPointF& p)
+{
+ QVector<QPointF> points;
+ points.push_back(cursorPos);
+ points.push_back(QPointF(cursorPos.x() - CONTROL_POINT_CURSOR_W/2, cursorPos.y() + CONTROL_POINT_CURSOR_H/2));
+ points.push_back(QPointF(cursorPos.x(), cursorPos.y() + CONTROL_POINT_CURSOR_H));
+ points.push_back(QPointF(cursorPos.x() + CONTROL_POINT_CURSOR_W/2, cursorPos.y() + CONTROL_POINT_CURSOR_H/2));
+ points.push_back(cursorPos);
+ QPolygonF polygon(points);
+ return polygon.containsPoint(p, Qt::OddEvenFill);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool isClickedInWeightCursor(const QPointF& cursorPos, const QPointF& p)
+{
+ QVector<QPointF> points;
+ points.push_back(cursorPos);
+ points.push_back(QPointF(cursorPos.x() - WEIGHT_CURSOR_W/2, cursorPos.y() + WEIGHT_CURSOR_H/2));
+ points.push_back(QPointF(cursorPos.x(), cursorPos.y() + WEIGHT_CURSOR_H));
+ points.push_back(QPointF(cursorPos.x() + WEIGHT_CURSOR_W/2, cursorPos.y() + WEIGHT_CURSOR_H/2));
+ points.push_back(cursorPos);
+ QPolygonF polygon(points);
+ return polygon.containsPoint(p, Qt::OddEvenFill);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+QImage genControlPointCursorImg(const QColor& color, bool picked = false)
+{
+ int w = CONTROL_POINT_CURSOR_W;
+ int h = CONTROL_POINT_CURSOR_H;
+ QImage image = QImage(w, h, QImage::Format_ARGB32);
+ image.fill(QColor(0, 0, 0, 0));
+
+ QPainter painter(&image);
+ painter.setRenderHints(QPainter::Antialiasing,true);
+
+ QPainterPath path;
+ path.moveTo(w>>1, 0);
+ path.lineTo(0, h>>1);
+ path.lineTo(w>>1, h);
+ path.lineTo(w, h>>1);
+ path.lineTo(w>>1, 0);
+ if (picked)
+ {
+ painter.setPen(QPen(Qt::green, 1, Qt::SolidLine));
+ painter.drawPath(path);
+ }
+
+ painter.fillPath(path, QBrush(color));
+
+ return image;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+ColorWidget::ColorWidget(QWidget *parent) :
+ QFrame(parent),
+ _isLink(false),
+ _colorAttribute(nullptr),
+ _colorCurve(nullptr),
+ _alphaCurve(nullptr),
+ _canAddRemoveControlPoint(false),
+ _canAddCtrlPntByClick(false),
+ _canRemoveCtrlPntByClick(false),
+ _curveFitWindowScale(1),
+ _curveFitWindowOffset(0),
+ _pickedColorCtrlPnt(-1),
+ _pickedAlphaCtrlPnt(-1),
+ _pickedColorWeight(-1),
+ _pickedAlphaWeight(-1),
+ _dragColorCtrlPnt(false),
+ _dragAlphaCtrlPnt(false),
+ _dragColorWeight(false),
+ _dragAlphaWeight(false),
+ _colorCtrlPntToRemove(-1),
+ _alphaCtrlPntToRemove(-1),
+ _contextMenu(nullptr),
+ _removeCtrlPntAction(nullptr)
+{
+ setFocusPolicy(Qt::ClickFocus );
+
+ InitCursorResources();
+
+ setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(onShowContextMenu(const QPoint&)));
+
+ _contextMenu = new QMenu(this);;
+ _removeCtrlPntAction = new QAction(this);
+ _removeCtrlPntAction->setText(tr("Remove Control Point"));
+ _contextMenu->addAction(_removeCtrlPntAction);
+
+ connect(_removeCtrlPntAction, SIGNAL(triggered()), this, SLOT(onRemoveControlPoint()) );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+QColor ColorWidget::getColor()
+{
+ QColor color;
+ if (_pickedColorCtrlPnt != -1)
+ {
+ color = _colorCurve->getControlPoint(_pickedColorCtrlPnt).color;
+ }
+ return color;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+int ColorWidget::getAlpha()
+{
+ if (_pickedAlphaCtrlPnt != -1)
+ {
+ if (_isLink)
+ {
+ return _colorCurve->getControlPoint(_pickedAlphaCtrlPnt).color.alpha();
+ }
+ else
+ {
+ return _alphaCurve->getControlPoint(_pickedAlphaCtrlPnt).color.alpha();
+ }
+ }
+ return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::setColor(const QColor& color)
+{
+ if (_pickedColorCtrlPnt != -1)
+ {
+ ColorControlPoint pickedColorPnt = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+
+ pickedColorPnt.color.setRed(color.red());
+ pickedColorPnt.color.setGreen(color.green());
+ pickedColorPnt.color.setBlue(color.blue());
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt, pickedColorPnt);
+
+ emit ColorAttributeChanged(_colorAttribute);
+ update();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::setAlpha(int alpha)
+{
+ if (_pickedColorCtrlPnt != -1)
+ {
+ ColorControlPoint pickedColorPnt = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ pickedColorPnt.color.setAlpha(alpha);
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt, pickedColorPnt);
+
+ emit ColorAttributeChanged(_colorAttribute);
+ update();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+float ColorWidget::getColorFallOff()
+{
+ if (_colorCurve && -1 != _pickedColorCtrlPnt)
+ {
+ const ColorControlPoint& pnt = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ return pnt.fallOff;
+ }
+ return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::setColorFallOff(float fallOff)
+{
+ if (_colorCurve && -1 != _pickedColorCtrlPnt)
+ {
+ ColorControlPoint pnt = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ pnt.fallOff = fallOff;
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt, pnt);
+ emit ColorAttributeChanged(_colorAttribute);
+ update();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+float ColorWidget::getAlphaFallOff()
+{
+ if (_isLink)
+ {
+ if (_colorCurve && -1 != _pickedColorCtrlPnt)
+ {
+ const ColorControlPoint& pnt = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ return pnt.fallOff;
+ }
+ }
+ else
+ {
+ if (_alphaCurve && -1 != _pickedAlphaCtrlPnt)
+ {
+ const ColorControlPoint& pnt = _alphaCurve->getControlPoint(_pickedAlphaCtrlPnt);
+ return pnt.fallOff;
+ }
+ }
+ return 0;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::setAlphaFallOff(float fallOff)
+{
+ if (_isLink)
+ {
+ if (_colorCurve && -1 != _pickedColorCtrlPnt)
+ {
+ ColorControlPoint pnt = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ pnt.fallOff = fallOff;
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt, pnt);
+ emit ColorAttributeChanged(_colorAttribute);
+ update();
+ }
+ }
+ else
+ {
+ if (_alphaCurve && -1 != _pickedAlphaCtrlPnt)
+ {
+ ColorControlPoint pnt = _alphaCurve->getControlPoint(_pickedAlphaCtrlPnt);
+ pnt.fallOff = fallOff;
+ _alphaCurve->setControlPoint(_pickedAlphaCtrlPnt, pnt);
+
+ emit ColorAttributeChanged(_colorAttribute);
+ update();
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::setColorAttribute(ColorAttribute* colorAttribute)
+{
+ _colorAttribute = colorAttribute;
+ if (colorAttribute != nullptr)
+ {
+ _colorCurve = &(colorAttribute->colorCurve);
+ _alphaCurve = &(colorAttribute->alphaCurve);
+ }
+ else
+ {
+ _colorCurve = nullptr;
+ _alphaCurve = nullptr;
+ }
+
+ if (_alphaCurve !=nullptr && _alphaCurve->getControlPointCount() < 2)
+ {
+ _isLink = true;
+ }
+ else
+ {
+ _isLink = false;
+ }
+
+ _pickedColorCtrlPnt = -1;
+ _pickedAlphaCtrlPnt = -1;
+ _pickedColorWeight = -1;
+ _pickedAlphaWeight = -1;
+ _dragColorCtrlPnt = false;
+ _dragAlphaCtrlPnt = false;
+ _dragColorWeight = false;
+ _dragAlphaWeight = false;
+
+ _updateCurveFitWindowPara();
+ if (_colorCurve)
+ _colorCurve->_needSample = true;
+ if (_alphaCurve)
+ _alphaCurve->_needSample = true;
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::reset()
+{
+ if (_colorAttribute)
+ {
+ _colorAttribute->colorCurve.reset();
+ _colorAttribute->alphaCurve.reset();
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::addControlPointsBeforeSelected()
+{
+ if (-1 != _pickedColorCtrlPnt)
+ {
+ if (_pickedColorCtrlPnt == 0)
+ return;
+
+ _colorCurve->insertControlPointAt(_pickedColorCtrlPnt);
+ ++_pickedColorCtrlPnt;
+ }
+ else if (-1 != _pickedAlphaCtrlPnt)
+ {
+ if (_pickedAlphaCtrlPnt == 0)
+ return;
+
+ _alphaCurve->insertControlPointAt(_pickedAlphaCtrlPnt);
+ ++_pickedAlphaCtrlPnt;
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::addControlPointsAfterSelected()
+{
+ if (-1 != _pickedColorCtrlPnt )
+ {
+ _colorCurve->insertControlPointAt(_pickedColorCtrlPnt + 1);
+ }
+ else if (-1 != _pickedAlphaCtrlPnt)
+ {
+ _alphaCurve->insertControlPointAt(_pickedAlphaCtrlPnt + 1);
+ }
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::removeSelectedControlPoint()
+{
+ if (-1 != _pickedColorCtrlPnt)
+ {
+ _colorCurve->removeControlPoint(_pickedColorCtrlPnt);
+ _pickedColorCtrlPnt = -1;
+ }
+ else if (-1 != _pickedAlphaCtrlPnt)
+ {
+ _alphaCurve->removeControlPoint(_pickedAlphaCtrlPnt);
+ _pickedAlphaCtrlPnt = -1;
+ }
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::setTangentType(InterpolateMode mode)
+{
+ if (-1 != _pickedColorCtrlPnt)
+ {
+ ColorControlPoint pnt = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ pnt.mode = mode;
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt, pnt);
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+ else if (-1 != _pickedAlphaCtrlPnt)
+ {
+ ColorControlPoint pnt = _alphaCurve->getControlPoint(_pickedColorCtrlPnt);
+ pnt.mode = mode;
+ _alphaCurve->setControlPoint(_pickedColorCtrlPnt, pnt);
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::setSmoothTangent()
+{
+ if (-1 != _pickedColorCtrlPnt && _pickedColorCtrlPnt < (_colorCurve->getControlPointCount() - 1) )
+ {
+ ColorControlPoint ctrlctrlPntFront = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ ctrlctrlPntFront.mode = eBezierSpline;
+ ctrlctrlPntFront.splineData.outLen = 1.0;
+ ctrlctrlPntFront.splineData.outTan = 0;
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt, ctrlctrlPntFront);
+
+ ColorControlPoint ctrlPntBehiand = _colorCurve->getControlPoint(_pickedColorCtrlPnt + 1);
+ ctrlPntBehiand.mode = eBezierSpline;
+ ctrlPntBehiand.splineData.inLen = 1.0;
+ ctrlPntBehiand.splineData.inTan = 0.0;
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt + 1, ctrlPntBehiand);
+
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+ else if (-1 != _pickedAlphaCtrlPnt && _pickedAlphaCtrlPnt < (_alphaCurve->getControlPointCount() - 1) )
+ {
+ ColorControlPoint ctrlctrlPntFront = _alphaCurve->getControlPoint(_pickedColorCtrlPnt);
+ ctrlctrlPntFront.mode = eBezierSpline;
+ ctrlctrlPntFront.splineData.outLen = 1.0;
+ ctrlctrlPntFront.splineData.outTan = 0;
+ _alphaCurve->setControlPoint(_pickedColorCtrlPnt, ctrlctrlPntFront);
+
+ ColorControlPoint ctrlPntBehiand = _alphaCurve->getControlPoint(_pickedColorCtrlPnt + 1);
+ ctrlPntBehiand.mode = eBezierSpline;
+ ctrlPntBehiand.splineData.inLen = 1.0;
+ ctrlPntBehiand.splineData.inTan = 0.0;
+ _alphaCurve->setControlPoint(_pickedColorCtrlPnt + 1, ctrlPntBehiand);
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::setEaseInTangent()
+{
+ if (-1 != _pickedColorCtrlPnt && _pickedColorCtrlPnt < (_colorCurve->getControlPointCount() - 1) )
+ {
+ ColorControlPoint ctrlctrlPntFront = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ ctrlctrlPntFront.mode = eBezierSpline;
+ ctrlctrlPntFront.splineData.outLen = 0.0;
+ ctrlctrlPntFront.splineData.outTan = 0;
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt, ctrlctrlPntFront);
+
+ ColorControlPoint ctrlPntBehiand = _colorCurve->getControlPoint(_pickedColorCtrlPnt + 1);
+ ctrlPntBehiand.mode = eBezierSpline;
+ ctrlPntBehiand.splineData.inLen = 1.0;
+ ctrlPntBehiand.splineData.inTan = 0;
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt + 1, ctrlPntBehiand);
+
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+ else if (-1 != _pickedAlphaCtrlPnt && _pickedAlphaCtrlPnt < (_alphaCurve->getControlPointCount() - 1) )
+ {
+ ColorControlPoint ctrlctrlPntFront = _alphaCurve->getControlPoint(_pickedColorCtrlPnt);
+ ctrlctrlPntFront.mode = eBezierSpline;
+ ctrlctrlPntFront.splineData.outLen = 0.0;
+ ctrlctrlPntFront.splineData.outTan = 0;
+ _alphaCurve->setControlPoint(_pickedColorCtrlPnt, ctrlctrlPntFront);
+
+ ColorControlPoint ctrlPntBehiand = _alphaCurve->getControlPoint(_pickedColorCtrlPnt + 1);
+ ctrlPntBehiand.mode = eBezierSpline;
+ ctrlPntBehiand.splineData.inLen = 1.0;
+ ctrlPntBehiand.splineData.inTan = 0;
+ _alphaCurve->setControlPoint(_pickedColorCtrlPnt + 1, ctrlPntBehiand);
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::setEaseOutTangent()
+{
+ if (-1 != _pickedColorCtrlPnt && _pickedColorCtrlPnt < (_colorCurve->getControlPointCount() - 1) )
+ {
+ ColorControlPoint ctrlctrlPntFront = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ ctrlctrlPntFront.mode = eBezierSpline;
+ ctrlctrlPntFront.splineData.outLen = 1.0;
+ ctrlctrlPntFront.splineData.outTan = 0;
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt, ctrlctrlPntFront);
+
+ ColorControlPoint ctrlPntBehiand = _colorCurve->getControlPoint(_pickedColorCtrlPnt + 1);
+ ctrlPntBehiand.mode = eBezierSpline;
+ ctrlPntBehiand.splineData.inLen = 0.0;
+ ctrlPntBehiand.splineData.inTan = 0;
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt + 1, ctrlPntBehiand);
+
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+ else if (-1 != _pickedAlphaCtrlPnt && _pickedAlphaCtrlPnt < (_alphaCurve->getControlPointCount() - 1) )
+ {
+ ColorControlPoint ctrlctrlPntFront = _alphaCurve->getControlPoint(_pickedColorCtrlPnt);
+ ctrlctrlPntFront.mode = eBezierSpline;
+ ctrlctrlPntFront.splineData.outLen = 1.0;
+ ctrlctrlPntFront.splineData.outTan = 0;
+ _alphaCurve->setControlPoint(_pickedColorCtrlPnt, ctrlctrlPntFront);
+
+ ColorControlPoint ctrlPntBehiand = _alphaCurve->getControlPoint(_pickedColorCtrlPnt + 1);
+ ctrlPntBehiand.mode = eBezierSpline;
+ ctrlPntBehiand.splineData.inLen = 0.0;
+ ctrlPntBehiand.splineData.inTan = 0;
+ _alphaCurve->setControlPoint(_pickedColorCtrlPnt + 1, ctrlPntBehiand);
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+QString ColorWidget::getColorTex()
+{
+ if (-1 != _pickedColorCtrlPnt)
+ {
+ ColorControlPoint pnt = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ return pnt.texturePath.c_str();
+ }
+ return "";
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::setColorTex(const QString& strPath)
+{
+ if (-1 != _pickedColorCtrlPnt)
+ {
+ ColorControlPoint pnt = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ pnt.texturePath = strPath.toStdString();
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt, pnt);
+ emit ColorAttributeChanged(_colorAttribute);
+ update();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::reloadColorTex()
+{
+ if (-1 != _pickedColorCtrlPnt)
+ {
+ emit ReloadColorAttributeTexture(_colorAttribute, true, _pickedColorCtrlPnt);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::clearColorTex()
+{
+ if (-1 != _pickedColorCtrlPnt)
+ {
+ ColorControlPoint pnt = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ pnt.texturePath = "";
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt, pnt);
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+QString ColorWidget::getAlphaTex()
+{
+ if (-1 != _pickedColorCtrlPnt && _isLink)
+ {
+ ColorControlPoint pnt = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ return pnt.texturePath.c_str();
+ }
+ else if (-1 != _pickedAlphaCtrlPnt)
+ {
+ ColorControlPoint pnt = _alphaCurve->getControlPoint(_pickedAlphaCtrlPnt);
+ return pnt.texturePath.c_str();
+ }
+
+ return "";
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::setAlphaTex(const QString& strPath)
+{
+ if (-1 != _pickedColorCtrlPnt && _isLink)
+ {
+ ColorControlPoint pnt = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ pnt.texturePath = strPath.toStdString();
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt, pnt);
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+ else if (-1 != _pickedAlphaCtrlPnt)
+ {
+ ColorControlPoint pnt = _alphaCurve->getControlPoint(_pickedAlphaCtrlPnt);
+ pnt.texturePath = strPath.toStdString();
+ _alphaCurve->setControlPoint(_pickedColorCtrlPnt, pnt);
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::reloadAlphaTex()
+{
+ if (-1 != _pickedColorCtrlPnt && _isLink)
+ {
+ emit ReloadColorAttributeTexture(_colorAttribute, false, _pickedColorCtrlPnt);
+ }
+ else if (-1 != _pickedAlphaCtrlPnt)
+ {
+ emit ReloadColorAttributeTexture(_colorAttribute, false, _pickedAlphaCtrlPnt);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::clearAlphaTex()
+{
+ if (-1 != _pickedColorCtrlPnt && _isLink)
+ {
+ ColorControlPoint pnt = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ pnt.texturePath = "";
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt, pnt);
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+ else if (-1 != _pickedAlphaCtrlPnt)
+ {
+ ColorControlPoint pnt = _alphaCurve->getControlPoint(_pickedAlphaCtrlPnt);
+ pnt.texturePath = "";
+ _alphaCurve->setControlPoint(_pickedColorCtrlPnt, pnt);
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::setUseAlphaFromColor(bool val)
+{
+ if (_colorAttribute && _colorAttribute->useAlphaFromColor != val)
+ {
+ _colorAttribute->useAlphaFromColor = val;
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::onShowContextMenu(const QPoint& pos)
+{
+ _colorCtrlPntToRemove = _checkColorCtrlPntCursorSelected(pos);
+ _alphaCtrlPntToRemove = _checkAlphaCtrlPntCursorSelected(pos);
+
+ if ( !_canAddRemoveControlPoint
+ || (-1 == _colorCtrlPntToRemove && -1 == _alphaCtrlPntToRemove)
+ || 2 == _colorCurve->_controlPoints.size() && -1 != _colorCtrlPntToRemove
+ || 2 == _alphaCurve->_controlPoints.size() && -1 != _alphaCtrlPntToRemove)
+ {
+ _removeCtrlPntAction->setEnabled(false);
+ }
+ else
+ {
+ _removeCtrlPntAction->setEnabled(true);
+ }
+ _contextMenu->exec(QCursor::pos());
+}
+
+void ColorWidget::onRemoveControlPoint()
+{
+ if (-1 != _colorCtrlPntToRemove)
+ {
+ _colorCurve->removeControlPoint(_colorCtrlPntToRemove);
+
+ if (_colorCtrlPntToRemove == _pickedColorCtrlPnt)
+ {
+ if (_isLink)
+ {
+ _colorCtrlPntToRemove = -1;
+ _pickedColorCtrlPnt = -1;
+ _pickedAlphaCtrlPnt = -1;
+ }
+ else
+ {
+ _colorCtrlPntToRemove = -1;
+ _pickedColorCtrlPnt = -1;
+ }
+ }
+
+ _colorCurve->_needSample = true;
+ emit ColorAttributeChanged(_colorAttribute);
+ update();
+ }
+ else if (-1 != _alphaCtrlPntToRemove && _isLink)
+ {
+ _colorCurve->removeControlPoint(_alphaCtrlPntToRemove);
+
+ if (_alphaCtrlPntToRemove == _pickedAlphaCtrlPnt)
+ {
+ _alphaCtrlPntToRemove = -1;
+ _pickedColorCtrlPnt = -1;
+ _pickedAlphaCtrlPnt = -1;
+ }
+
+ _colorCurve->_needSample = true;
+ emit ColorAttributeChanged(_colorAttribute);
+ update();
+ }
+ else if (-1 != _alphaCtrlPntToRemove && !_isLink)
+ {
+ _alphaCurve->removeControlPoint(_alphaCtrlPntToRemove);
+
+ if (_alphaCtrlPntToRemove == _pickedAlphaCtrlPnt)
+ {
+ _colorCtrlPntToRemove = -1;
+ _pickedColorCtrlPnt = -1;
+ }
+
+ _alphaCurve->_needSample = true;
+ emit ColorAttributeChanged(_colorAttribute);
+ update();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool ColorWidget::event(QEvent *event)
+{
+ if (event->type() == QEvent::ToolTip) {
+ QHelpEvent* helpEvent = static_cast<QHelpEvent*>(event);
+ QPoint mousePos = helpEvent->pos();
+
+ QPointF mousePosF(mousePos.x(), mousePos.y());
+ int pickedColorCtrlPnt = _checkColorCtrlPntCursorSelected(mousePosF);
+ int pickedAlphaCtrlPnt = _checkAlphaCtrlPntCursorSelected(mousePosF);
+
+ if (-1 != pickedColorCtrlPnt)
+ {
+ const std::string& tex = _colorCurve->getControlPoint(pickedColorCtrlPnt).texturePath;
+ if (!tex.empty())
+ QToolTip::showText(helpEvent->globalPos(), tex.c_str());
+
+ }
+ else if (-1 != pickedAlphaCtrlPnt)
+ {
+ if (_isLink)
+ {
+ const std::string& tex = _colorCurve->getControlPoint(pickedAlphaCtrlPnt).texturePath;
+ if (!tex.empty())
+ QToolTip::showText(helpEvent->globalPos(), tex.c_str());
+ }
+ else
+ {
+ const std::string& tex = _alphaCurve->getControlPoint(pickedAlphaCtrlPnt).texturePath;
+ if (!tex.empty())
+ QToolTip::showText(helpEvent->globalPos(), tex.c_str());
+ }
+ }
+ else
+ {
+ QToolTip::hideText();
+ event->ignore();
+ }
+
+ return true;
+ }
+ return QWidget::event(event);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::paintEvent(QPaintEvent * e)
+{
+ //TimeConsumeTracker t("update");
+ QFrame::paintEvent(e);
+
+ QPainter painter;
+ painter.begin(this);
+ painter.setRenderHints(QPainter::Antialiasing, true);
+
+ if (_colorCurve)
+ {
+ _drawRampArea(painter);
+ _drawCtrlPntCursors(painter);
+ _drawWeightCursors(painter);
+ }
+ painter.end();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::resizeEvent(QResizeEvent* e)
+{
+ if (_colorCurve)
+ _updateCurveFitWindowPara();
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::mousePressEvent( QMouseEvent* e )
+{
+ if(_colorCurve && e->button() & Qt::LeftButton)
+ {
+ QPoint mousePos = e->pos();
+ QPointF mousePosF(mousePos.x(), mousePos.y());
+ int pickedColorCtrlPnt = _checkColorCtrlPntCursorSelected(mousePosF);
+ int pickedAlphaCtrlPnt = _checkAlphaCtrlPntCursorSelected(mousePosF);
+
+ if (-1 != pickedColorCtrlPnt || -1 != pickedAlphaCtrlPnt)
+ {
+ if (_canAddRemoveControlPoint && _canRemoveCtrlPntByClick)
+ {
+ if (-1 != pickedColorCtrlPnt)
+ {
+ _colorCurve->removeControlPoint(pickedColorCtrlPnt);
+ _pickedColorCtrlPnt = -1;
+ }
+
+ if (-1 != pickedAlphaCtrlPnt)
+ {
+ if (_isLink)
+ {
+ _colorCurve->removeControlPoint(pickedAlphaCtrlPnt);
+ _pickedColorCtrlPnt = -1;
+ pickedAlphaCtrlPnt = -1;
+ }
+ else
+ {
+ _alphaCurve->removeControlPoint(pickedAlphaCtrlPnt);
+ pickedAlphaCtrlPnt = -1;
+ }
+ }
+ return;
+ }
+
+ _pickedColorCtrlPnt = pickedColorCtrlPnt;
+ _pickedAlphaCtrlPnt = pickedAlphaCtrlPnt;
+
+ if (-1 < _pickedColorCtrlPnt)
+ _dragColorCtrlPnt = true;
+
+ if (-1 < _pickedAlphaCtrlPnt)
+ _dragAlphaCtrlPnt = true;
+
+ if (_isLink)
+ {
+ if (-1 != pickedColorCtrlPnt)
+ {
+ _pickedAlphaCtrlPnt = _pickedColorCtrlPnt;
+ _dragAlphaCtrlPnt = _dragColorCtrlPnt;
+ }
+
+ if (-1 != pickedAlphaCtrlPnt)
+ {
+ _pickedColorCtrlPnt = _pickedAlphaCtrlPnt;
+ _dragColorCtrlPnt = _dragAlphaCtrlPnt;
+ }
+ PickedControlPointChanged(true);
+ }
+ else
+ {
+ if (-1 != pickedColorCtrlPnt)
+ {
+ PickedControlPointChanged(true);
+ }
+
+ if (-1 != pickedAlphaCtrlPnt)
+ {
+ PickedControlPointChanged(false);
+ }
+ }
+
+
+ }
+ else
+ {
+ int pickedColorWeight = _checkColorWeightCursorSelected(mousePosF);
+ int pickedAlphaWeight = _checkAlphaWeightCursorSelected(mousePosF);
+
+ if (-1 != pickedColorWeight || -1 != pickedAlphaWeight)
+ {
+ _pickedColorWeight = pickedColorWeight;
+ _pickedAlphaWeight = pickedAlphaWeight;
+
+ if (-1 < _pickedColorWeight)
+ _dragColorWeight = true;
+
+ if (-1 < _pickedAlphaCtrlPnt)
+ _dragAlphaWeight = true;
+
+ if (_isLink)
+ {
+ if (-1 != _pickedColorWeight)
+ {
+ _pickedAlphaWeight = _pickedColorWeight;
+ _dragAlphaWeight = _dragColorWeight;
+ }
+
+ if (-1 != _pickedAlphaWeight)
+ {
+ _pickedColorWeight = _pickedAlphaWeight;
+ _dragColorWeight = _dragAlphaWeight;
+ }
+ }
+ }
+ else
+ {
+ if (_canAddRemoveControlPoint && _canAddCtrlPntByClick)
+ {
+ int yMiddle = height() / 2;
+ if (mousePos.y() <= yMiddle)
+ {
+ _addColorControlPoint(mousePos.x());
+ PickedControlPointChanged(true);
+ }
+ else if (mousePos.y() > yMiddle)
+ {
+ if (_isLink)
+ {
+ _addColorControlPoint(mousePos.x());
+ PickedControlPointChanged(true);
+ }
+ else
+ {
+ _addAlphaControlPoint(mousePos.x());
+ PickedControlPointChanged(false);
+ }
+ }
+ }
+ }
+ }
+ update();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::mouseReleaseEvent( QMouseEvent* /*e*/ )
+{
+ _dragColorCtrlPnt = false;
+ _dragAlphaCtrlPnt = false;
+ _dragColorWeight = false;
+ _dragAlphaWeight = false;
+ _pickedColorWeight = -1;
+ _pickedAlphaWeight = -1;
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::mouseMoveEvent( QMouseEvent* e )
+{
+ Qt::MouseButtons buttons = e->buttons();
+
+ if(_colorCurve && buttons & Qt::LeftButton)
+ {
+ if (_dragColorCtrlPnt)
+ {
+ if (!_colorAttribute->canMoveControlPointHorizontally())
+ return;
+
+ QPoint mousePos = e->pos();
+ ColorControlPoint pnt = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ pnt.x = _screenToValue(mousePos.x());
+
+ //make control point move in value range
+ if (pnt.x < _colorCurve->getMinValue())
+ pnt.x = _colorCurve->getMinValue();
+ else if (pnt.x > _colorCurve->getMaxValue())
+ pnt.x = _colorCurve->getMaxValue();
+
+ _colorCurve->setControlPoint(_pickedColorCtrlPnt, pnt);
+ _colorCurve->_reOrderControlPoints(_pickedColorCtrlPnt);
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+
+ if (_dragColorWeight)
+ {
+ QPoint mousePos = e->pos();
+ ColorControlPoint pnt0 = _colorCurve->getControlPoint(_pickedColorWeight);
+ ColorControlPoint pnt1 = _colorCurve->getControlPoint(_pickedColorWeight + 1);
+ int xPnt0Screen = _valueToScreen(pnt0.x);
+ int xPnt1Screen = _valueToScreen(pnt1.x);
+ if (mousePos.x() < (xPnt0Screen + WEIGHT_CURSOR_W))
+ mousePos.setX(xPnt0Screen + WEIGHT_CURSOR_W);
+ if (mousePos.x() > (xPnt1Screen - WEIGHT_CURSOR_W))
+ mousePos.setX(xPnt1Screen - WEIGHT_CURSOR_W);
+ pnt0.weight = ((float)(mousePos.x() - xPnt0Screen))/(xPnt1Screen - xPnt0Screen);
+ _colorCurve->setControlPoint(_pickedColorWeight, pnt0);
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+
+ if (!_isLink)
+ {
+ if (_dragAlphaCtrlPnt)
+ {
+ if (!_colorAttribute->canMoveControlPointHorizontally())
+ return;
+
+ QPoint mousePos = e->pos();
+ ColorControlPoint pnt = _alphaCurve->getControlPoint(_pickedAlphaCtrlPnt);
+ pnt.x = _screenToValue(mousePos.x());
+
+ //make control point move in value range
+ if (pnt.x < _alphaCurve->getMinValue())
+ pnt.x = _alphaCurve->getMinValue();
+ else if (pnt.x > _alphaCurve->getMaxValue())
+ pnt.x = _alphaCurve->getMaxValue();
+
+ _alphaCurve->setControlPoint(_pickedAlphaCtrlPnt, pnt);
+ _alphaCurve->_reOrderControlPoints(_pickedAlphaCtrlPnt);
+ _alphaCurve->_needSample = true;
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+
+ if (_dragAlphaWeight)
+ {
+ QPoint mousePos = e->pos();
+ ColorControlPoint pnt0 = _alphaCurve->getControlPoint(_pickedAlphaWeight);
+ ColorControlPoint pnt1 = _alphaCurve->getControlPoint(_pickedAlphaWeight + 1);
+ int xPnt0Screen = _valueToScreen(pnt0.x);
+ int xPnt1Screen = _valueToScreen(pnt1.x);
+ if (mousePos.x() < (xPnt0Screen + WEIGHT_CURSOR_W))
+ mousePos.setX(xPnt0Screen + WEIGHT_CURSOR_W);
+ if (mousePos.x() > (xPnt1Screen - WEIGHT_CURSOR_W))
+ mousePos.setX(xPnt1Screen - WEIGHT_CURSOR_W);
+ pnt0.weight = ((float)(mousePos.x() - xPnt0Screen))/(xPnt1Screen - xPnt0Screen);
+ _alphaCurve->setControlPoint(_pickedAlphaWeight, pnt0);
+ emit ColorAttributeChanged(_colorAttribute);
+ }
+ }
+
+ update();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::_updateCurveFitWindowPara()
+{
+ int widgetWidth = width();
+
+ if (_colorCurve && _colorCurve->getControlPointCount() > 1)
+ {
+ float minX = _colorCurve->getMinValue();
+ float maxX = _colorCurve->getMaxValue();
+
+ if (!_isLink)
+ {
+ if (minX < _alphaCurve->getMinValue())
+ minX = _alphaCurve->getMinValue();
+
+ if (maxX < _alphaCurve->getMaxValue())
+ maxX = _alphaCurve->getMaxValue();
+ }
+
+ float curveWidth = maxX - minX;
+
+ if (0 == curveWidth)
+ {
+ curveWidth = 1.0;
+ }
+
+ _curveFitWindowScale = (widgetWidth - MARGIN_X * 2) / curveWidth;
+ _curveFitWindowOffset = MARGIN_X - minX * _curveFitWindowScale;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+float ColorWidget::_valueToScreen(float x)
+{
+ return ROUND(_curveFitWindowScale * x + _curveFitWindowOffset);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+float ColorWidget::_screenToValue(float x)
+{
+ return (x - _curveFitWindowOffset) / _curveFitWindowScale;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void ColorWidget::_fillRampImage(QImage& colorImg, QImage& alphaImg)
+{
+ assert(colorImg.width() == alphaImg.width());
+ assert(colorImg.height() == alphaImg.height());
+
+ int width = colorImg.width();
+ int height = colorImg.height();
+
+ QRgb *colorPixels = nullptr;
+ QRgb *alphaPixels = nullptr;
+ {
+ colorPixels = new QRgb[width];
+ //TimeConsumeTracker t("calcuate one line colorPixels");
+ for (int i = 0; i < width; ++i)
+ {
+ colorPixels[i] = _colorCurve->getColorByX(_screenToValue(i + MARGIN_X)).rgba();
+ }
+
+ if (!_isLink)
+ {
+ alphaPixels = new QRgb[width];
+ //TimeConsumeTracker t("calcuate one line alphaPixels");
+ for (int i = 0; i < width; ++i)
+ {
+ alphaPixels[i] = _alphaCurve->getColorByX(_screenToValue(i + MARGIN_X)).rgba();
+ }
+ }
+ }
+
+ {
+ //TimeConsumeTracker tt("fill images' pixel");
+ for (int m = 0; m < height; ++m)
+ {
+ void* bytesPerLine = const_cast<uchar*>(colorImg.scanLine(m));
+ memcpy(bytesPerLine, colorPixels, sizeof(QRgb) * width);
+
+ bytesPerLine = const_cast<uchar*>(alphaImg.scanLine(m));
+ if (nullptr == alphaPixels)
+ memcpy(bytesPerLine, colorPixels, sizeof(QRgb) * width);
+ else
+ memcpy(bytesPerLine, alphaPixels, sizeof(QRgb) * width);
+ }
+ }
+
+ delete[] colorPixels;
+}
+
+void ColorWidget::_drawRampArea(QPainter& painter)
+{
+ QImage colorImg(width() - MARGIN_X * 2, (height() - SPACING_V - CONTROL_POINT_CURSOR_H * 2 - MARGIN_Y * 2) / 2, QImage::Format_RGB32);
+ QImage alphaImg(width() - MARGIN_X * 2, (height() - SPACING_V - CONTROL_POINT_CURSOR_H * 2 - MARGIN_Y * 2) / 2, QImage::Format_RGB32);
+ _fillRampImage(colorImg, alphaImg);
+ painter.drawImage(MARGIN_X, MARGIN_Y + CONTROL_POINT_CURSOR_H, colorImg);
+ painter.drawImage(MARGIN_X, MARGIN_Y + CONTROL_POINT_CURSOR_H + (height() - SPACING_V - CONTROL_POINT_CURSOR_H * 2 - MARGIN_Y * 2) / 2, alphaImg);
+}
+
+void ColorWidget::_drawCtrlPntCursors(QPainter& painter)
+{
+ int colorCtrlPntCount = _colorCurve->getControlPointCount();
+
+ for (int i = 0; i < colorCtrlPntCount; ++i)
+ {
+ const ColorControlPoint& pnt = _colorCurve->getControlPoint(i);
+
+ float xPosCtrlPnt = ROUND(_valueToScreen(pnt.x));
+ float yColorCtrlPnt = MARGIN_Y;
+ float yAlphaCtrlPnt = height() - SPACING_V - CONTROL_POINT_CURSOR_H - MARGIN_Y;
+
+ QRect rcColorCtrnPntCursor(xPosCtrlPnt - CONTROL_POINT_CURSOR_W / 2, yColorCtrlPnt, CONTROL_POINT_CURSOR_W, CONTROL_POINT_CURSOR_H);
+ QRect rcAlphaCtrnPntCursor(xPosCtrlPnt - CONTROL_POINT_CURSOR_W / 2, yAlphaCtrlPnt, CONTROL_POINT_CURSOR_W, CONTROL_POINT_CURSOR_H);
+ if (i == _pickedColorCtrlPnt)
+ {
+ if (pnt.texturePath.empty())
+ painter.drawImage(rcColorCtrnPntCursor, genControlPointCursorImg(QColor(pnt.color.red(), pnt.color.green(), pnt.color.blue(), 255), true));
+ else
+ painter.drawImage(rcColorCtrnPntCursor, S_CtrlPntWithTexCursorPickedImg);
+
+ if (_isLink)
+ {
+ if (pnt.texturePath.empty())
+ painter.drawImage(rcAlphaCtrnPntCursor, genControlPointCursorImg(QColor(pnt.color.alpha(), pnt.color.alpha(), pnt.color.alpha()), true));
+ else
+ painter.drawImage(rcAlphaCtrnPntCursor, S_CtrlPntWithTexCursorPickedImg);
+ }
+ }
+ else
+ {
+ if (pnt.texturePath.empty())
+ painter.drawImage(rcColorCtrnPntCursor, genControlPointCursorImg(QColor(pnt.color.red(), pnt.color.green(), pnt.color.blue(), 255)));
+ else
+ painter.drawImage(rcColorCtrnPntCursor, S_CtrlPntWithTexCursorNormalImg);
+
+ if (_isLink)
+ {
+ if (pnt.texturePath.empty())
+ painter.drawImage(rcAlphaCtrnPntCursor, genControlPointCursorImg(QColor(pnt.color.alpha(), pnt.color.alpha(), pnt.color.alpha())));
+ else
+ painter.drawImage(rcAlphaCtrnPntCursor, S_CtrlPntWithTexCursorNormalImg);
+ }
+
+ }
+ }
+
+ if (!_isLink)
+ {
+ int alphaCtrlPntCount = _alphaCurve->getControlPointCount();
+
+ for (int i = 0; i < alphaCtrlPntCount; ++i)
+ {
+ const ColorControlPoint& pnt = _alphaCurve->getControlPoint(i);
+
+ float xPosCtrlPnt = ROUND(_valueToScreen(pnt.x));
+ float yAlphaCtrlPnt = height() - SPACING_V - CONTROL_POINT_CURSOR_H - MARGIN_Y;
+
+ QRect rcAlphaCtrnPntCursor(xPosCtrlPnt - CONTROL_POINT_CURSOR_W / 2, yAlphaCtrlPnt, CONTROL_POINT_CURSOR_W, CONTROL_POINT_CURSOR_H);
+
+ if (i == _pickedAlphaCtrlPnt)
+ {
+ if (pnt.texturePath.empty())
+ painter.drawImage(rcAlphaCtrnPntCursor, genControlPointCursorImg(QColor(pnt.color.alpha(), pnt.color.alpha(), pnt.color.alpha()), true));
+ else
+ painter.drawImage(rcAlphaCtrnPntCursor, S_CtrlPntWithTexCursorPickedImg);
+ }
+ else
+ {
+ if (pnt.texturePath.empty())
+ painter.drawImage(rcAlphaCtrnPntCursor, genControlPointCursorImg(QColor(pnt.color.alpha(), pnt.color.alpha(), pnt.color.alpha()) ));
+ else
+ painter.drawImage(rcAlphaCtrnPntCursor, S_CtrlPntWithTexCursorNormalImg);
+ }
+ }
+ }
+}
+
+void ColorWidget::_drawWeightCursors(QPainter& painter)
+{
+ float yColorWeight = MARGIN_Y + CONTROL_POINT_CURSOR_H - WEIGHT_CURSOR_H;
+
+ int colorCtrlPntCount = _colorCurve->getControlPointCount();
+ if (0 == _pickedColorCtrlPnt)
+ {
+ const ColorControlPoint& pnt0 = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ const ColorControlPoint& pnt1 = _colorCurve->getControlPoint(_pickedColorCtrlPnt + 1);
+
+ _drawColorWeightCursor(painter, pnt0, pnt1, _pickedColorCtrlPnt == _pickedColorWeight);
+ }
+ else if ((colorCtrlPntCount - 1) == _pickedColorCtrlPnt)
+ {
+ const ColorControlPoint& pnt0 = _colorCurve->getControlPoint(_pickedColorCtrlPnt - 1);
+ const ColorControlPoint& pnt1 = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+
+ _drawColorWeightCursor(painter, pnt0, pnt1, (_pickedColorCtrlPnt - 1) == _pickedColorWeight);
+ }
+ else if (0 < _pickedColorCtrlPnt && _pickedColorCtrlPnt < (colorCtrlPntCount - 1))
+ {
+ const ColorControlPoint& pnt0 = _colorCurve->getControlPoint(_pickedColorCtrlPnt - 1);
+ const ColorControlPoint& pnt1 = _colorCurve->getControlPoint(_pickedColorCtrlPnt);
+ const ColorControlPoint& pnt2 = _colorCurve->getControlPoint(_pickedColorCtrlPnt + 1);
+
+ _drawColorWeightCursor(painter, pnt0, pnt1, (_pickedColorCtrlPnt - 1) == _pickedColorWeight);
+ _drawColorWeightCursor(painter, pnt1, pnt2, _pickedColorCtrlPnt == _pickedColorWeight);
+ }
+
+ if (!_isLink)
+ {
+ float yAlphaWeight = height() - SPACING_V - WEIGHT_CURSOR_H - MARGIN_Y;
+ int alphaCtrlPntCount = _alphaCurve->getControlPointCount();
+ if (0 == _pickedAlphaCtrlPnt)
+ {
+ const ColorControlPoint& pnt0 = _alphaCurve->getControlPoint(_pickedAlphaCtrlPnt);
+ const ColorControlPoint& pnt1 = _alphaCurve->getControlPoint(_pickedAlphaCtrlPnt + 1);
+
+ _drawAlphaWeightCursor(painter, pnt0, pnt1, _pickedAlphaCtrlPnt == _pickedAlphaWeight);
+ }
+ else if ((alphaCtrlPntCount - 1) == _pickedAlphaCtrlPnt)
+ {
+ const ColorControlPoint& pnt0 = _alphaCurve->getControlPoint(_pickedAlphaCtrlPnt - 1);
+ const ColorControlPoint& pnt1 = _alphaCurve->getControlPoint(_pickedAlphaCtrlPnt);
+
+ _drawAlphaWeightCursor(painter, pnt0, pnt1, (_pickedAlphaCtrlPnt - 1) == _pickedAlphaWeight);
+ }
+ else if (0 < _pickedAlphaCtrlPnt && _pickedAlphaCtrlPnt < (alphaCtrlPntCount - 1))
+ {
+ const ColorControlPoint& pnt0 = _alphaCurve->getControlPoint(_pickedAlphaCtrlPnt - 1);
+ const ColorControlPoint& pnt1 = _alphaCurve->getControlPoint(_pickedAlphaCtrlPnt);
+ const ColorControlPoint& pnt2 = _alphaCurve->getControlPoint(_pickedAlphaCtrlPnt + 1);
+
+ _drawAlphaWeightCursor(painter, pnt0, pnt1, (_pickedAlphaCtrlPnt - 1) == _pickedAlphaWeight);
+ _drawAlphaWeightCursor(painter, pnt1, pnt2, _pickedAlphaCtrlPnt == _pickedAlphaWeight);
+ }
+ }
+}
+
+void ColorWidget::_drawColorWeightCursor(QPainter& painter, const ColorControlPoint& pnt0, const ColorControlPoint& pnt1, bool picked)
+{
+ if (pnt0.mode != eLinear)
+ return ;
+
+ float yColorWeight = MARGIN_Y + CONTROL_POINT_CURSOR_H - WEIGHT_CURSOR_H;
+ float yAlphaWeight = height() - SPACING_V - CONTROL_POINT_CURSOR_H - MARGIN_Y;
+
+ float xPosWeightCursor = ROUND(_valueToScreen(pnt0.x + pnt0.weight * (pnt1.x - pnt0.x)));
+ QRect rcColorWeightCursor(xPosWeightCursor - WEIGHT_CURSOR_W / 2, yColorWeight, WEIGHT_CURSOR_W, WEIGHT_CURSOR_H);
+ QRect rcAlphaWeightCursor(xPosWeightCursor - WEIGHT_CURSOR_W / 2, yAlphaWeight, WEIGHT_CURSOR_W, WEIGHT_CURSOR_H);
+
+ painter.drawImage(rcColorWeightCursor, picked?S_WeightCursorPickedImg:S_WeightCursorNormalImg);
+
+ if (_isLink)
+ painter.drawImage(rcAlphaWeightCursor, picked?S_WeightCursorPickedImg:S_WeightCursorNormalImg);
+}
+
+void ColorWidget::_drawAlphaWeightCursor(QPainter& painter, const ColorControlPoint& pnt0, const ColorControlPoint& pnt1, bool picked)
+{
+ if (pnt0.mode != eLinear)
+ return ;
+
+ float yColorWeight = MARGIN_Y + CONTROL_POINT_CURSOR_H - WEIGHT_CURSOR_H;
+ float yAlphaWeight = height() - SPACING_V - CONTROL_POINT_CURSOR_H - MARGIN_Y;
+
+ float xPosWeightCursor = ROUND(_valueToScreen(pnt0.x + pnt0.weight * (pnt1.x - pnt0.x)));
+ QRect rcColorWeightCursor(xPosWeightCursor - WEIGHT_CURSOR_W / 2, yColorWeight, WEIGHT_CURSOR_W, WEIGHT_CURSOR_H);
+ QRect rcAlphaWeightCursor(xPosWeightCursor - WEIGHT_CURSOR_W / 2, yAlphaWeight, WEIGHT_CURSOR_W, WEIGHT_CURSOR_H);
+
+ painter.drawImage(rcAlphaWeightCursor, picked?S_WeightCursorPickedImg:S_WeightCursorNormalImg);
+
+ if (_isLink)
+ painter.drawImage(rcColorWeightCursor, picked?S_WeightCursorPickedImg:S_WeightCursorNormalImg);
+}
+
+int ColorWidget::_checkColorCtrlPntCursorSelected(const QPointF& pickPos)
+{
+ if (nullptr == _colorCurve)
+ return -1;
+ int colorCtrlPntCount = _colorCurve->getControlPointCount();
+ for (int i = 0; i < colorCtrlPntCount; ++i)
+ {
+ const ColorControlPoint& pnt = _colorCurve->getControlPoint(i);
+
+ float xPos = _valueToScreen(pnt.x);
+ float yPos = MARGIN_Y;
+ bool picked = isClickedInCtrlPntCursor(QPointF(xPos, yPos), pickPos);
+ if (picked)
+ {
+ return i;
+ }
+ }
+
+ return -1;
+}
+
+int ColorWidget::_checkAlphaCtrlPntCursorSelected(const QPointF& pickPos)
+{
+ if (_isLink)
+ {
+ if (nullptr == _colorCurve)
+ return -1;
+ int colorCtrlPntCount = _colorCurve->getControlPointCount();
+ for (int i = 0; i < colorCtrlPntCount; ++i)
+ {
+ const ColorControlPoint& pnt = _colorCurve->getControlPoint(i);
+
+ float xPos = _valueToScreen(pnt.x);
+ float yPos = height() - SPACING_V - CONTROL_POINT_CURSOR_H - MARGIN_Y;
+ bool picked = isClickedInCtrlPntCursor(QPointF(xPos, yPos), pickPos);
+ if (picked)
+ {
+ return i;
+ }
+ }
+ }
+ else
+ {
+ if (nullptr == _alphaCurve)
+ return -1;
+ int colorCtrlPntCount = _alphaCurve->getControlPointCount();
+ for (int i = 0; i < colorCtrlPntCount; ++i)
+ {
+ const ColorControlPoint& pnt = _alphaCurve->getControlPoint(i);
+
+ float xPos = _valueToScreen(pnt.x);
+ float yPos = height() - SPACING_V - CONTROL_POINT_CURSOR_H - MARGIN_Y;
+ bool picked = isClickedInCtrlPntCursor(QPointF(xPos, yPos), pickPos);
+ if (picked)
+ {
+ return i;
+ }
+ }
+ }
+
+ return -1;
+}
+
+int ColorWidget::_checkColorWeightCursorSelected(const QPointF& pickPos)
+{
+ int colorCtrlPntCount = _colorCurve->getControlPointCount();
+ if (-1 != _pickedColorCtrlPnt)
+ {
+ if (0 == _pickedColorCtrlPnt)
+ {
+ return _checkColorWeightCursorSelected(0, pickPos);
+ }
+ else if ((colorCtrlPntCount - 1) == _pickedColorCtrlPnt)
+ {
+ return _checkColorWeightCursorSelected(_pickedColorCtrlPnt - 1, pickPos);
+ }
+ else if (0 < _pickedColorCtrlPnt && _pickedColorCtrlPnt < (colorCtrlPntCount - 1))
+ {
+ int pickedWeightCursor = _checkColorWeightCursorSelected(_pickedColorCtrlPnt - 1, pickPos);
+ if (-1 != pickedWeightCursor)
+ return pickedWeightCursor;
+ else
+ return _checkColorWeightCursorSelected(_pickedColorCtrlPnt, pickPos);
+ }
+ }
+
+ return -1;
+}
+
+int ColorWidget::_checkColorWeightCursorSelected(int pickedCtrlPnt, const QPointF& pickPos)
+{
+ const ColorControlPoint& pnt0 = _colorCurve->getControlPoint(pickedCtrlPnt);
+ const ColorControlPoint& pnt1 = _colorCurve->getControlPoint(pickedCtrlPnt + 1);
+
+ if (pnt0.weight >= 0)
+ {
+ float xPos = _valueToScreen(pnt0.x + pnt0.weight * (pnt1.x - pnt0.x));
+ float yPos = MARGIN_Y + CONTROL_POINT_CURSOR_H - WEIGHT_CURSOR_H;
+ bool picked = isClickedInWeightCursor(QPointF(xPos, yPos), pickPos);
+ if (picked)
+ {
+ return pickedCtrlPnt;
+ }
+ }
+
+ return - 1;
+}
+
+int ColorWidget::_checkAlphaWeightCursorSelected(const QPointF& pickPos)
+{
+ if (_isLink)
+ {
+ int count = _colorCurve->getControlPointCount();
+ if (-1 != _pickedAlphaCtrlPnt)
+ {
+ if (0 == _pickedAlphaCtrlPnt)
+ {
+ return _checkAlphaWeightCursorSelected(0, pickPos);
+ }
+ else if ((count - 1) == _pickedAlphaCtrlPnt)
+ {
+ return _checkAlphaWeightCursorSelected(_pickedColorCtrlPnt - 1, pickPos);
+ }
+ else if (0 < _pickedAlphaCtrlPnt && _pickedAlphaCtrlPnt < (count - 1))
+ {
+ int pickedWeightCursor = _checkAlphaWeightCursorSelected(_pickedColorCtrlPnt - 1, pickPos);
+ if (-1 != pickedWeightCursor)
+ return pickedWeightCursor;
+ else
+ return _checkAlphaWeightCursorSelected(_pickedColorCtrlPnt, pickPos);
+ }
+ }
+ }
+ else
+ {
+ int count = _alphaCurve->getControlPointCount();
+ if (-1 != _pickedAlphaCtrlPnt)
+ {
+ if (0 == _pickedAlphaCtrlPnt)
+ {
+ return _checkAlphaWeightCursorSelected(0, pickPos);
+ }
+ else if ((count - 1) == _pickedAlphaCtrlPnt)
+ {
+ return _checkAlphaWeightCursorSelected(count - 1, pickPos);
+ }
+ else if (0 < _pickedAlphaCtrlPnt && _pickedAlphaCtrlPnt < (count - 1))
+ {
+ int pickedWeightCursor = _checkAlphaWeightCursorSelected(_pickedColorCtrlPnt - 1, pickPos);
+ if (-1 != pickedWeightCursor)
+ return pickedWeightCursor;
+ else
+ return _checkAlphaWeightCursorSelected(_pickedColorCtrlPnt, pickPos);
+ }
+ }
+ }
+
+ return -1;
+}
+
+int ColorWidget::_checkAlphaWeightCursorSelected(int pickedCtrlPnt, const QPointF& pickPos)
+{
+ if (_isLink)
+ {
+ const ColorControlPoint& pnt0 = _colorCurve->getControlPoint(pickedCtrlPnt);
+ const ColorControlPoint& pnt1 = _colorCurve->getControlPoint(pickedCtrlPnt + 1);
+
+ if (pnt0.weight >= 0)
+ {
+ float xPos = _valueToScreen(pnt0.x + pnt0.weight * (pnt1.x - pnt0.x));
+ float yPos = height() - SPACING_V - CONTROL_POINT_CURSOR_H - MARGIN_Y;
+ bool picked = isClickedInWeightCursor(QPointF(xPos, yPos), pickPos);
+ if (picked)
+ {
+ return pickedCtrlPnt;
+ }
+ }
+ }
+ else
+ {
+ int colorCtrlPntCount = _alphaCurve->getControlPointCount();
+ for (int i = 0; i < colorCtrlPntCount - 1; ++i)
+ {
+ const ColorControlPoint& pnt0 = _alphaCurve->getControlPoint(i);
+ const ColorControlPoint& pnt1 = _alphaCurve->getControlPoint(i + 1);
+
+ if (pnt0.weight >= 0)
+ {
+ float xPos = _valueToScreen(pnt0.x + pnt0.weight * (pnt1.x - pnt0.x));
+ float yPos = height() - SPACING_V - CONTROL_POINT_CURSOR_H - MARGIN_Y;
+ bool picked = isClickedInCtrlPntCursor(QPointF(xPos, yPos), pickPos);
+ if (picked)
+ {
+ return i;
+ }
+ }
+ else
+ break;
+ }
+ }
+
+ return -1;
+}
+
+void ColorWidget::_addColorControlPoint(int xPos)
+{
+ float x = _screenToValue(xPos);
+
+ int ctrlPntCount = _colorCurve->getControlPointCount();
+ for (int i = 0; i < ctrlPntCount - 1; ++i)
+ {
+ const ColorControlPoint& pntLeft = _colorCurve->getControlPoint(i);
+ const ColorControlPoint& pntRight = _colorCurve->getControlPoint(i + 1);
+
+ if (pntLeft.x < x && x < pntRight.x)
+ {
+ QColor color = _colorCurve->getColorByX(x);
+ ColorControlPoint newCtrlPnt(x, color, pntLeft.mode);
+
+ std::vector<ColorControlPoint>::iterator itr = _colorCurve->_controlPoints.begin();
+ std::advance(itr, i + 1);
+ _colorCurve->_controlPoints.insert(itr, newCtrlPnt);
+
+ _pickedColorCtrlPnt = i + 1;
+ if (_isLink)
+ _pickedAlphaCtrlPnt = _pickedColorCtrlPnt;
+
+ break;
+ }
+ }
+}
+
+void ColorWidget::_addAlphaControlPoint(int xPos)
+{
+ float x = _screenToValue(xPos);
+
+ int ctrlPntCount = _alphaCurve->getControlPointCount();
+ for (int i = 0; i < ctrlPntCount - 1; ++i)
+ {
+ const ColorControlPoint& pntLeft = _alphaCurve->getControlPoint(i);
+ const ColorControlPoint& pntRight = _alphaCurve->getControlPoint(i + 1);
+
+ if (pntLeft.x < x && x < pntRight.x)
+ {
+ QColor color = _alphaCurve->getColorByX(x);
+ ColorControlPoint newCtrlPnt(x, color, pntLeft.mode);
+
+ std::vector<ColorControlPoint>::iterator itr = _alphaCurve->_controlPoints.begin();
+ std::advance(itr, i + 1);
+ _alphaCurve->_controlPoints.insert(itr, newCtrlPnt);
+
+ _pickedAlphaCtrlPnt = i + 1;
+ if (_isLink)
+ _pickedColorCtrlPnt = _pickedAlphaCtrlPnt;
+
+ break;
+ }
+ }
+}
+
+} // namespace CurveEditor
+} // namespace nvidia \ No newline at end of file
diff --git a/tools/CurveEditor/source/Internal/Window/ColorWidget.h b/tools/CurveEditor/source/Internal/Window/ColorWidget.h
new file mode 100644
index 0000000..d910789
--- /dev/null
+++ b/tools/CurveEditor/source/Internal/Window/ColorWidget.h
@@ -0,0 +1,126 @@
+#ifndef COLORWIDGET_H
+#define COLORWIDGET_H
+
+#include <QtWidgets/QFrame>
+#include <QtWidgets/QMenu>
+#include <QtWidgets/QAction>
+#include "Attribute.h"
+
+namespace nvidia {
+namespace CurveEditor {
+
+class ColorWidget : public QFrame
+{
+ Q_OBJECT
+public:
+ explicit ColorWidget(QWidget *parent = 0);
+
+ inline bool isLink() { return _isLink; }
+ QColor getColor();
+ int getAlpha();
+ void setColor(const QColor& color);
+ void setAlpha(int alpha);
+ float getColorFallOff();
+ void setColorFallOff(float fallOff);
+ float getAlphaFallOff();
+ void setAlphaFallOff(float fallOff);
+
+ // if alphaCurve of colorAttribute is with less than 2 control points,
+ // it treats that rgb color curve and alpha curve share same control points
+ // else, it uses rgb components of colorCurve of ColorAttribute, and it uses alpha component of alphaCurve of ColorAttribute
+ void setColorAttribute(ColorAttribute* colorAttribute);
+ void reset();
+ inline void setCanAddRemoveControlPoint(bool val) { _canAddRemoveControlPoint = val; }
+
+ void addControlPointsBeforeSelected();
+ void addControlPointsAfterSelected();
+ void removeSelectedControlPoint();
+
+ void setTangentType(InterpolateMode mode);
+ void setSmoothTangent();
+ void setEaseInTangent();
+ void setEaseOutTangent();
+
+ QString getColorTex();
+ void setColorTex(const QString& strPath);
+ void reloadColorTex();
+ void clearColorTex();
+ QString getAlphaTex();
+ void setAlphaTex(const QString& strPath);
+ void reloadAlphaTex();
+ void clearAlphaTex();
+
+ void setAddCtrlPntByClick(bool value) { _canAddCtrlPntByClick = value; }
+ void setRemoveCtrlPntByClick(bool value) { _canRemoveCtrlPntByClick = value; }
+
+ void setUseAlphaFromColor(bool val);
+
+signals:
+ void PickedControlPointChanged(bool isColorCtrlPnt);
+ void ColorAttributeChanged(nvidia::CurveEditor::ColorAttribute* attribute);
+ void ReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute* attribute, bool reloadColorTex, int selectedCtrlPntIndex);
+
+private slots:
+ void onShowContextMenu(const QPoint& pos);
+ void onRemoveControlPoint();
+
+protected:
+ // QWidget events
+ virtual bool event(QEvent *event);
+ virtual void paintEvent(QPaintEvent * e);
+ virtual void resizeEvent(QResizeEvent* e);
+ virtual void mousePressEvent(QMouseEvent* e);
+ virtual void mouseReleaseEvent(QMouseEvent* e);
+ virtual void mouseMoveEvent(QMouseEvent* e);
+
+private:
+ void _updateCurveFitWindowPara();
+ inline float _valueToScreen(float x);
+ inline float _screenToValue(float x);
+
+ void _fillRampImage(QImage& colorImg, QImage& alphaImg);
+ void _drawRampArea(QPainter& painter);
+ void _drawCtrlPntCursors(QPainter& painter);
+ void _drawWeightCursors(QPainter& painter);
+ void _drawColorWeightCursor(QPainter& painter, const ColorControlPoint& pnt0, const ColorControlPoint& pnt1, bool picked = false);
+ void _drawAlphaWeightCursor(QPainter& painter, const ColorControlPoint& pnt0, const ColorControlPoint& pnt1, bool picked = false);
+ int _checkColorCtrlPntCursorSelected(const QPointF& pickPos);
+ int _checkAlphaCtrlPntCursorSelected(const QPointF& pickPos);
+ int _checkColorWeightCursorSelected(const QPointF& pickPos);
+ int _checkColorWeightCursorSelected(int pickedCtrlPnt, const QPointF& pickPos);
+ int _checkAlphaWeightCursorSelected(const QPointF& pickPos);
+ int _checkAlphaWeightCursorSelected(int pickedCtrlPnt, const QPointF& pickPos);
+ void _addColorControlPoint(int xPos);
+ void _addAlphaControlPoint(int xPos);
+
+private:
+ bool _isLink; // if it's true, rgb color and alpha share the same control points
+ ColorAttribute* _colorAttribute;
+ ColorCurve* _colorCurve;
+ ColorCurve* _alphaCurve;
+ bool _canAddRemoveControlPoint;
+ bool _canAddCtrlPntByClick;
+ bool _canRemoveCtrlPntByClick;
+
+ float _curveFitWindowScale;
+ float _curveFitWindowOffset;
+
+ int _pickedColorCtrlPnt;
+ int _pickedAlphaCtrlPnt;
+ int _pickedColorWeight;
+ int _pickedAlphaWeight;
+ bool _dragColorCtrlPnt;
+ bool _dragAlphaCtrlPnt;
+ bool _dragColorWeight;
+ bool _dragAlphaWeight;
+
+ int _colorCtrlPntToRemove;
+ int _alphaCtrlPntToRemove;
+ QMenu* _contextMenu;
+ QAction* _removeCtrlPntAction;
+};
+
+} // namespace CurveEditor
+} // namespace nvidia
+
+#endif // COLORWIDGET_H
diff --git a/tools/CurveEditor/source/Internal/Window/CurveEditorMainWindow.cpp b/tools/CurveEditor/source/Internal/Window/CurveEditorMainWindow.cpp
new file mode 100644
index 0000000..b11c4cf
--- /dev/null
+++ b/tools/CurveEditor/source/Internal/Window/CurveEditorMainWindow.cpp
@@ -0,0 +1,1530 @@
+#include "CurveEditorMainWindow.h"
+#include "ui_CurveEditorMainWindow.h"
+#include <QtWidgets/QSplitter>
+#include <QtWidgets/QColorDialog>
+#include "CurveWidget.h"
+#include "ColorWidget.h"
+#include "AlphaDialog.h"
+#include <QtCore/QDebug>
+#include <QtWidgets/QFileDialog>
+#include <QtWidgets/QMessageBox>
+#include <float.h>
+
+namespace nvidia {
+namespace CurveEditor {
+
+// each value is associated with the tab index of tab control of attributes
+enum AttributesTabIndex
+{
+ eCurveTab = 0,
+ eColorTab = 1,
+};
+
+/////////////////////////////////////////////////////////////////////////////////////
+QString InterpolateModeToString(InterpolateMode mode)
+{
+ switch(mode)
+ {
+ case eDiscret:
+ return "Discret";
+ case eLinear:
+ return "Linear";
+ case eBezierSpline:
+ return "BezierSpline";
+ case eCatmullRomSpline:
+ return "CatmullRomSpline";
+ default:
+ return "Discret";
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+InterpolateMode StringToInterpolateMode(const QString& mode)
+{
+ if (mode == "Discret")
+ {
+ return eDiscret;
+ }
+ else if (mode == "Linear")
+ {
+ return eLinear;
+ }
+ else if (mode == "BezierSpline")
+ {
+ return eBezierSpline;
+ }
+ else if (mode == "CatmullRomSpline")
+ {
+ return eCatmullRomSpline;
+ }
+ else
+ {
+ return eDiscret;
+ }
+}
+
+QString OpenTextureFile( QString lastDir, QString title = "")
+{
+ QString titleStr = "Open Texture File";
+ if(!title.isEmpty())
+ titleStr = title;
+
+ QString fileName = QFileDialog::getOpenFileName(nullptr, titleStr, lastDir, "Images (*.dds *.png *.bmp *.jpg *.tga)");
+
+ return fileName;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+void setTextureButtons(QPushButton *pTex, QPushButton *pReload, QPushButton *pClear)
+{
+ pTex->setIcon(QIcon(":/AppMainWindow/Icon/TextureEnabled_icon.png"));
+ pReload->setIcon(QIcon(":/AppMainWindow/Icon/Refresh_icon.png"));
+ pClear->setIcon(QIcon(":/AppMainWindow/Icon/Remove_icon.png"));
+
+ pTex->setIconSize(QSize(12,12));
+ pReload->setIconSize(QSize(12,12));
+ pClear->setIconSize(QSize(12,12));
+}
+
+//////////////////////////////////////////////////////////
+QString addStar(QString text, bool add)
+{
+ QByteArray ba = text.toUtf8();
+
+ const char* in = ba.data();
+ char out[1024];
+
+ int i = 0;
+ for (i = 0; i < strlen(in); i++)
+ {
+ if (in[i] == '*')
+ break;
+ out[i] = in[i];
+ }
+ out[i] = 0;
+
+ QString newtext;
+ if (add)
+ newtext = QString((const char*)out) + QString("*");
+ else
+ newtext = QString((const char*)out) ;
+ return newtext;
+}
+
+//////////////////////////////////////////////////////////
+void setFocusColor(QWidget* qWidget, bool sameForAllAttributes)
+{
+ if (!qWidget)
+ return;
+
+ QString sameStyle = QString("font: ; color: rgb(150,150,150);") ;
+ QString differentStyle = QString("font: bold; color: rgb(255,55,55);");
+ QString style = (sameForAllAttributes) ? sameStyle : differentStyle;
+
+ qWidget->setStyleSheet(style);
+
+ QLabel* label = dynamic_cast<QLabel*>(qWidget);
+ if (label)
+ {
+ QString newtext = addStar(label->text(), !sameForAllAttributes);
+
+ label->setFrameStyle(0);
+ label->setText(newtext);
+ }
+}
+
+//////////////////////////////////////////////////////////
+void pickColor(QColor& color, QWidget* parent)
+{
+ QColor newColor = QColorDialog::getColor(color, parent);
+ if(newColor.isValid())
+ {
+ color = newColor;
+ }
+}
+
+//////////////////////////////////////////////////////////
+void pickAlpha(int& alpha, QWidget* parent)
+{
+ alpha = AlphaDialog::getAlpha(alpha, parent);
+}
+
+//////////////////////////////////////////////////////////
+void setButtonColor(QPushButton *button, const QColor& color)
+{
+ QString specBtnStyle = QString("background-color: rgb(%1,%2,%3);")
+ .arg(color.red())
+ .arg(color.green())
+ .arg(color.blue());
+
+ button->setStyleSheet(specBtnStyle);
+}
+
+//////////////////////////////////////////////////////////
+void setButtonTex(QPushButton *button, bool used)
+{
+ if (used)
+ button->setIcon(QIcon(":/AppMainWindow/Icon/TextureIsUsed_icon.png"));
+ else
+ button->setIcon(QIcon(":/AppMainWindow/Icon/TextureEnabled_icon.png"));
+}
+
+CurveEditorMainWindow::CurveEditorMainWindow(QWidget *parent)
+ : QMainWindow(parent)
+ , ui(new Ui::CurveEditorMainWindow)
+ , _curveWidget(nullptr)
+ , _colorWidget(nullptr)
+ , _curveAttributeCache(nullptr)
+ , _colorAttributeCache(nullptr)
+ , _updateUIFromData(false)
+ , _canMoveCurveControlPointHorizontally(true)
+ , _canAddRemoveCurveControlPoint(true)
+ , _canChangeCurveTangentType(true)
+{
+ Q_INIT_RESOURCE(CurveEditor);
+
+ ui->setupUi(this);
+
+ setTextureButtons(ui->btnColorTex, ui->btnColorReload, ui->btnColorClear);
+ setTextureButtons(ui->btnAlphaTex, ui->btnAlphaReload, ui->btnAlphaClear);
+
+ ui->centralWidget->setStretchFactor(0, 30);
+ ui->centralWidget->setStretchFactor(1, 70);
+
+ {
+ QActionGroup* groupSnap = new QActionGroup(this);
+ groupSnap->addAction(ui->actionSnap_All);
+ groupSnap->addAction(ui->actionSnap_Horizontal);
+ groupSnap->addAction(ui->actionSnap_Vertical);
+ }
+
+ {
+ QActionGroup* groupAddRemoveCtrlPnt = new QActionGroup(this);
+ groupAddRemoveCtrlPnt->addAction(ui->actionAdd_Control_Point_By_Click);
+ groupAddRemoveCtrlPnt->addAction(ui->actionRemove_Control_Point_By_Click);
+ }
+
+ _fillCurveAttributesTree();
+
+ _fillColorAttributesTree();
+
+ {
+ _curveWidget = new CurveWidget(ui->frameCurveEditorArea);
+ ui->layoutCurveEditorArea->addWidget(_curveWidget);
+ connect(_curveWidget, SIGNAL(PickedControlPointChanged(const std::vector<CurveEntity*>)), this, SLOT(onCurvePickedControlPointChanged(const std::vector<CurveEntity*>)));
+ connect(_curveWidget, SIGNAL(PickedControlPointValueChanged(QPointF&)), this, SLOT(onCurvePickedControlPointValueChanged(QPointF&)));
+ }
+
+ {
+ _colorWidget = new ColorWidget(ui->frameColorAlphaRamp);
+ ui->layoutColorEditorArea->addWidget(_colorWidget);
+ connect(_colorWidget, SIGNAL(PickedControlPointChanged(bool)), this, SLOT(onColorPickedControlPointChanged(bool)));
+
+ QColor color = _colorWidget->getColor();
+ setButtonColor(ui->btnColor, color);
+ setButtonColor(ui->btnAlpha, QColor(color.alpha(), color.alpha(), color.alpha()));
+ }
+
+ connect(_curveWidget, SIGNAL(CurveAttributeChanged(nvidia::CurveEditor::CurveAttribute*)), this, SIGNAL(CurveAttributeChanged(nvidia::CurveEditor::CurveAttribute*)));
+ connect(_colorWidget, SIGNAL(ColorAttributeChanged(nvidia::CurveEditor::ColorAttribute*)), this, SIGNAL(ColorAttributeChanged(nvidia::CurveEditor::ColorAttribute*)));
+ connect(_colorWidget, SIGNAL(ReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute*, bool, int)), this, SIGNAL(ReloadColorAttributeTexture(nvidia::CurveEditor::ColorAttribute*, bool, int)));
+
+ QString defFilePath;
+
+ QString appDir = qApp->applicationDirPath();
+ QDir dir(appDir);
+ if (dir.cd("../../media"))
+ defFilePath = dir.absolutePath();
+
+ _lastFilePath = defFilePath;
+ _presetPath = _lastFilePath + "/Presets/";
+}
+
+CurveEditorMainWindow::~CurveEditorMainWindow()
+{
+ delete ui;
+ ui = nullptr;
+}
+
+void CurveEditorMainWindow::setCurveAttributes(const std::vector<CurveAttributeBase*>& attributes)
+{
+ _curveWidget->setCurveAttributes(std::vector<CurveAttributeBase*>());
+
+ _curveAttributes = attributes;
+ _fillCurveAttributesTree();
+
+ _canMoveCurveControlPointHorizontally = false;
+ _canAddRemoveCurveControlPoint = false;
+ _canChangeCurveTangentType = false;
+ size_t countAttributes = _curveAttributes.size();
+ for (size_t i = 0; i < countAttributes; ++i)
+ {
+ CurveAttributeBase* attribute = _curveAttributes[i];
+
+ if (attribute->getType() == eGroupAttr)
+ {
+ CurveAttributeGroup* attributeGroup = static_cast<CurveAttributeGroup*>(attribute);
+ size_t countAttributesInGroup = attributeGroup->attributes.size();
+ for (size_t j = 0; j < countAttributesInGroup; ++j)
+ {
+ CurveAttribute* attributeInGroup = static_cast<CurveAttribute*>(attributeGroup->attributes[j]);
+ if (attributeInGroup->canMoveControlPointHorizontally())
+ _canMoveCurveControlPointHorizontally = true;
+ if (attributeInGroup->canAddRemoveControlPoint())
+ _canAddRemoveCurveControlPoint = true;
+ if (attributeInGroup->canChangeTangentType())
+ _canChangeCurveTangentType = true;
+ }
+ }
+ else
+ {
+ CurveAttribute* attributeSecific = static_cast<CurveAttribute*>(attribute);
+ if (attributeSecific->canMoveControlPointHorizontally())
+ _canMoveCurveControlPointHorizontally = true;
+ if (attributeSecific->canAddRemoveControlPoint())
+ _canAddRemoveCurveControlPoint = true;
+ if (attributeSecific->canChangeTangentType())
+ _canChangeCurveTangentType = true;
+ }
+ }
+
+ ui->spinBoxLocation->setEnabled(_canMoveCurveControlPointHorizontally);
+ _syncUIStatusWithSelectedAttribute(_canAddRemoveCurveControlPoint, _canChangeCurveTangentType);
+}
+
+void CurveEditorMainWindow::setColorCurveAttributes(const std::vector<ColorAttribute*>& attributes)
+{
+ _colorWidget->setColorAttribute(nullptr);
+
+ _colorAttributes = attributes;
+ _fillColorAttributesTree();
+}
+
+void CurveEditorMainWindow::setSelectedCurveAttributes(const std::vector<CurveAttributeBase*>& attributes)
+{
+ ui->tabWidgetAttributes->setCurrentIndex(eCurveTab);
+
+ for (size_t i = 0; i < attributes.size(); ++i)
+ {
+ CurveAttributeBase* attribute = attributes[i];
+ QList<QTreeWidgetItem*> items = ui->treeWidgetCurveAttributes->findItems(attribute->getName().c_str(), Qt::MatchExactly);
+ if (items.size() > 0)
+ items[0]->setSelected(true);
+ }
+}
+
+void CurveEditorMainWindow::setSelectedColorAttribute(const ColorAttribute* attribute)
+{
+ ui->tabWidgetAttributes->setCurrentIndex(eColorTab);
+
+ if (attribute)
+ {
+ QList<QTreeWidgetItem*> items = ui->treeWidgetColorAttributes->findItems(attribute->getName().c_str(), Qt::MatchExactly);
+ if (items.size() > 0)
+ items[0]->setSelected(true);
+ }
+}
+
+void CurveEditorMainWindow::setResampleEnabled(bool enable)
+{
+ ui->checkBoxResamplePoints->setVisible(enable);
+ ui->spinBoxResamplePoints->setVisible(enable);
+ ui->checkBoxResamplePoints->setEnabled(enable);
+ ui->spinBoxResamplePoints->setEnabled(enable);
+}
+
+void CurveEditorMainWindow::on_actionCopy_triggered()
+{
+ if (eCurveTab == ui->tabWidgetAttributes->currentIndex())
+ {
+ QList<QTreeWidgetItem*> items = ui->treeWidgetCurveAttributes->selectedItems();
+ if (1 == items.count())
+ {
+ CurveAttributeTreeItem* item = static_cast<CurveAttributeTreeItem*>(items.at(0));
+
+ if (eSingleAttr == item->_attribute->getType())
+ {
+ if (_curveAttributeCache == nullptr)
+ _curveAttributeCache = new CurveAttribute("curveAttributeCache");
+
+ CurveAttribute* selectedAttribute = static_cast<CurveAttribute*>(item->_attribute);
+ _curveAttributeCache->curve = selectedAttribute->curve;
+ return ;
+ }
+ }
+
+ QMessageBox::warning(this, tr("Warning"), tr("You should select only one attribute to copy attribute data."));
+ }
+ else if (eColorTab == ui->tabWidgetAttributes->currentIndex())
+ {
+ QList<QTreeWidgetItem*> items = ui->treeWidgetColorAttributes->selectedItems();
+ if (1 == items.count())
+ {
+ ColorAttributeTreeItem* item = static_cast<ColorAttributeTreeItem*>(items.at(0));
+
+ if (eColorAttr == item->_attribute->getType())
+ {
+ if (_colorAttributeCache == nullptr)
+ _colorAttributeCache = new ColorAttribute("colorAttributeCache");
+
+ ColorAttribute* selectedAttribute = static_cast<ColorAttribute*>(item->_attribute);
+ _colorAttributeCache->colorCurve = selectedAttribute->colorCurve;
+ _colorAttributeCache->alphaCurve = selectedAttribute->alphaCurve;
+ return ;
+ }
+ }
+ }
+}
+
+void CurveEditorMainWindow::on_actionPaste_triggered()
+{
+ if (eCurveTab == ui->tabWidgetAttributes->currentIndex())
+ {
+ if (nullptr == _curveAttributeCache)
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("You should copy or load an curve attribute's data first."));
+ return ;
+ }
+
+ QList<QTreeWidgetItem*> items = ui->treeWidgetCurveAttributes->selectedItems();
+ if (1 == items.count())
+ {
+ CurveAttributeTreeItem* item = static_cast<CurveAttributeTreeItem*>(items.at(0));
+
+ if (eSingleAttr == item->_attribute->getType())
+ {
+ CurveAttribute* selectedAttribute = static_cast<CurveAttribute*>(item->_attribute);
+ bool compatible = true;
+ if (compatible)
+ {
+ selectedAttribute->curve = _curveAttributeCache->curve;
+ on_treeWidgetCurveAttributes_itemSelectionChanged();
+ CurveAttributeChanged(selectedAttribute);
+ }
+ else
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("The data types between the curve attribute copyed from and the curve attribute copy to are incompatible ."));
+ }
+ return ;
+ }
+ }
+
+ QMessageBox::warning(this, tr("Warning"), tr("You should select only one curve attribute to paste curve attribute data."));
+ }
+ else if (eColorTab == ui->tabWidgetAttributes->currentIndex())
+ {
+ if (nullptr == _colorAttributeCache)
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("You should copy or load an color attribute's data first."));
+ return ;
+ }
+
+ QList<QTreeWidgetItem*> items = ui->treeWidgetColorAttributes->selectedItems();
+ if (1 == items.count())
+ {
+ ColorAttributeTreeItem* item = static_cast<ColorAttributeTreeItem*>(items.at(0));
+
+ if (eColorAttr == item->_attribute->getType())
+ {
+ ColorAttribute* selectedAttribute = static_cast<ColorAttribute*>(item->_attribute);
+ bool compatible = true;
+ if (compatible)
+ {
+ selectedAttribute->colorCurve = _colorAttributeCache->colorCurve;
+ selectedAttribute->alphaCurve = _colorAttributeCache->alphaCurve;
+ on_treeWidgetColorAttributes_itemSelectionChanged();
+ ColorAttributeChanged(selectedAttribute);
+ }
+ else
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("The data types between copy from attribute and copy to attribute are incompatible ."));
+ }
+ return ;
+ }
+ }
+
+ QMessageBox::warning(this, tr("Warning"), tr("You should select only one attribute to paste attribute data."));
+ }
+}
+
+void CurveEditorMainWindow::on_actionSave_Selected_as_Preset_triggered()
+{
+ QDir dir(_presetPath);
+ if (!dir.exists())
+ dir.mkdir(_presetPath);
+
+ CurveAttribute* curveAttribute = nullptr;
+ ColorAttribute* colorAttribute = nullptr;
+ QString presetFile = _presetPath;
+
+ if (eCurveTab == ui->tabWidgetAttributes->currentIndex())
+ {
+ QList<QTreeWidgetItem*> items = ui->treeWidgetCurveAttributes->selectedItems();
+ if (1 != items.count())
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("You should select one attribute only to save preset."));
+ return ;
+ }
+
+ CurveAttributeTreeItem* item = static_cast<CurveAttributeTreeItem*>(items.at(0));
+
+ if (eSingleAttr != item->_attribute->getType())
+ {
+ return;
+ }
+
+ curveAttribute = static_cast<CurveAttribute*>(item->_attribute);
+ presetFile += curveAttribute->getName().c_str();
+ presetFile += ".cps";
+ }
+ else if (eColorTab == ui->tabWidgetAttributes->currentIndex())
+ {
+ QList<QTreeWidgetItem*> items = ui->treeWidgetColorAttributes->selectedItems();
+ if (1 != items.count())
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("You should select one attribute only to save preset."));
+ return ;
+ }
+
+ ColorAttributeTreeItem* item = static_cast<ColorAttributeTreeItem*>(items.at(0));
+
+ if (eColorAttr != item->_attribute->getType())
+ {
+ return;
+ }
+
+ colorAttribute = item->_attribute;
+ presetFile += colorAttribute->getName().c_str();
+ presetFile += ".cps";
+ }
+
+ QString filePath = QFileDialog::getSaveFileName(this, tr("Save Curve PreSet"), presetFile, tr("Curve PreSet(*.cps)"));
+ if (filePath.length() == 0)
+ {
+ QMessageBox::warning(this, tr("Path"), tr("You didn't select any files."));
+ return ;
+ }
+
+ QFileInfo fileInfo(filePath);
+ _presetPath = fileInfo.absoluteDir().absolutePath();
+ if (!_presetPath.endsWith("/"))
+ _presetPath += "/";
+
+ QFile file(filePath);
+ if (!file.open(QIODevice::WriteOnly|QIODevice::Truncate))
+ {
+ return;
+ }
+ QTextStream out(&file);
+
+ QDomDocument xmlDoc;
+ QDomElement rootElm = xmlDoc.createElement(tr("CurvePreSet"));
+ xmlDoc.appendChild(rootElm);
+
+ if (curveAttribute != nullptr)
+ {
+ _saveAttribute(rootElm, curveAttribute);
+ }
+ else if (colorAttribute != nullptr)
+ {
+ _saveAttribute(rootElm, colorAttribute);
+ }
+ // 4 is count of indent
+ xmlDoc.save(out, 4);
+}
+
+void CurveEditorMainWindow::on_actionLoad_Preset_to_Copy_Buffer_triggered()
+{
+ QString filePath = QFileDialog::getOpenFileName(this, tr("Open Curve PreSet"), _presetPath, tr("Curve PreSet(*.cps)"));
+ if (filePath.length() == 0)
+ {
+ QMessageBox::warning(this, tr("Path"), tr("You didn't select any files."));
+ return;
+ }
+
+ QFileInfo fileInfo(filePath);
+ _presetPath = fileInfo.absoluteDir().absolutePath();
+ if (!_presetPath.endsWith("/"))
+ _presetPath += "/";
+
+ QFile file(filePath);
+
+ if (!file.open(QIODevice::ReadOnly))
+ {
+ return;
+ }
+
+ QDomDocument xmlDoc;
+ if (!xmlDoc.setContent(&file))
+ {
+ file.close();
+ return;
+ }
+ file.close();
+
+ if (xmlDoc.isNull() || xmlDoc.documentElement().tagName() != tr("CurvePreSet"))
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("The file you selected is empty or not a cps file."));
+ return;
+ }
+
+ QDomElement elm = xmlDoc.documentElement().firstChildElement();
+ CurveAttributeBase* presetAttribute = _loadAttribute(elm);
+ if (nullptr == presetAttribute)
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("Faid to load the cps file!"));
+ return;
+ }
+
+ if (eSingleAttr == presetAttribute->_type)
+ {
+ if (_curveAttributeCache == nullptr)
+ _curveAttributeCache = new CurveAttribute("curveAttributeCache");
+
+ CurveAttribute* presetCurveAttribute = static_cast<CurveAttribute*>(presetAttribute);
+ _curveAttributeCache->curve = presetCurveAttribute->curve;
+ }
+ else if (eColorAttr == presetAttribute->_type)
+ {
+ if (_colorAttributeCache == nullptr)
+ _colorAttributeCache = new ColorAttribute("colorAttributeCache");
+
+ ColorAttribute* presetColorAttribute = static_cast<ColorAttribute*>(presetAttribute);
+ _colorAttributeCache->colorCurve = presetColorAttribute->colorCurve;
+ _colorAttributeCache->alphaCurve = presetColorAttribute->alphaCurve;
+ }
+}
+
+void CurveEditorMainWindow::on_actionImport_Preset_onto_Selected_triggered()
+{
+ CurveAttribute* curveAttribute = nullptr;
+ ColorAttribute* colorAttribute = nullptr;
+ if (eCurveTab == ui->tabWidgetAttributes->currentIndex())
+ {
+ QList<QTreeWidgetItem*> items = ui->treeWidgetCurveAttributes->selectedItems();
+ if (1 != items.count())
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("You should select only one attribute to import preset."));
+ return;
+ }
+
+ CurveAttributeTreeItem* item = static_cast<CurveAttributeTreeItem*>(items.at(0));
+
+ if (eSingleAttr != item->_attribute->getType())
+ {
+ return;
+ }
+
+ curveAttribute = static_cast<CurveAttribute*>(item->_attribute);
+ }
+ else if (eColorTab == ui->tabWidgetAttributes->currentIndex())
+ {
+ QList<QTreeWidgetItem*> items = ui->treeWidgetColorAttributes->selectedItems();
+ if (1 != items.count())
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("You should select only one attribute to import preset."));
+ return;
+ }
+
+ ColorAttributeTreeItem* item = static_cast<ColorAttributeTreeItem*>(items.at(0));
+
+ if (eColorAttr != item->_attribute->getType())
+ {
+ return;
+ }
+
+ colorAttribute = item->_attribute;
+ }
+
+ QString filePath = QFileDialog::getOpenFileName(this, tr("Open Curve PreSet"), _presetPath, tr("Curve PreSet(*.cps)"));
+ if (filePath.length() == 0)
+ {
+ QMessageBox::warning(this, tr("Path"), tr("You didn't select any files."));
+ return;
+ }
+
+ QFileInfo fileInfo(filePath);
+ _presetPath = fileInfo.absoluteDir().absolutePath();
+ if (!_presetPath.endsWith("/"))
+ _presetPath += "/";
+
+ QFile file(filePath);
+
+ if (!file.open(QIODevice::ReadOnly))
+ {
+ return;
+ }
+
+ QDomDocument xmlDoc;
+ if (!xmlDoc.setContent(&file))
+ {
+ file.close();
+ return;
+ }
+ file.close();
+
+ if (xmlDoc.isNull() || xmlDoc.documentElement().tagName() != tr("CurvePreSet"))
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("The file you selected is empty or not a cps file."));
+ return;
+ }
+
+ QDomElement elm = xmlDoc.documentElement().firstChildElement();
+ CurveAttributeBase* presetAttribute = _loadAttribute(elm);
+ if (nullptr == presetAttribute)
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("Faid to load the cps file!"));
+ return;
+ }
+
+ if (eSingleAttr == presetAttribute->_type)
+ {
+ CurveAttribute* presetCurveAttribute = static_cast<CurveAttribute*>(presetAttribute);
+
+ bool compatible = (curveAttribute != nullptr) ? true:false;
+ if (compatible)
+ {
+ curveAttribute->curve = presetCurveAttribute->curve;
+ on_treeWidgetCurveAttributes_itemSelectionChanged();
+ CurveAttributeChanged(curveAttribute);
+ }
+ else
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("The selected attribute is incompatible with preset attribute."));
+ }
+ }
+ else if (eColorAttr == presetAttribute->_type)
+ {
+ ColorAttribute* presetColorAttribute = static_cast<ColorAttribute*>(presetAttribute);
+
+ bool compatible = (colorAttribute != nullptr) ? true:false;;
+ if (compatible)
+ {
+ colorAttribute->colorCurve = presetColorAttribute->colorCurve;
+ colorAttribute->alphaCurve = presetColorAttribute->alphaCurve;
+ on_treeWidgetColorAttributes_itemSelectionChanged();
+ ColorAttributeChanged(colorAttribute);
+ }
+ else
+ {
+ QMessageBox::warning(this, tr("Warning"), tr("The selected attribute is incompatible with preset attribute."));
+ }
+ }
+}
+
+void CurveEditorMainWindow::on_actionReset_Curve_triggered()
+{
+ if (ui->tabWidgetAttributes->currentIndex() == eCurveTab)
+ {
+ _curveWidget->reset();
+ }
+ else if (ui->tabWidgetAttributes->currentIndex() == eColorTab)
+ {
+ _colorWidget->reset();
+ }
+
+}
+
+void CurveEditorMainWindow::on_actionAdd_Before_Selected_triggered()
+{
+ if (_curveWidget->hasFocus())
+ _curveWidget->addControlPointsBeforeSelected();
+
+ if (_colorWidget->hasFocus())
+ _colorWidget->addControlPointsBeforeSelected();
+}
+
+void CurveEditorMainWindow::on_actionAdd_After_Selected_triggered()
+{
+ if (_curveWidget->hasFocus())
+ _curveWidget->addControlPointsAfterSelected();
+
+ if (_colorWidget->hasFocus())
+ _colorWidget->addControlPointsAfterSelected();
+}
+
+void CurveEditorMainWindow::on_actionRemove_Selected_triggered()
+{
+ if (_curveWidget->hasFocus())
+ _curveWidget->removeSelectedControlPoints();
+
+ if (_colorWidget->hasFocus())
+ _colorWidget->removeSelectedControlPoint();
+}
+
+void CurveEditorMainWindow::on_actionTangent_Stepped_triggered()
+{
+ if (_curveWidget->hasFocus())
+ _curveWidget->setTangentType(eDiscret);
+
+ if (_colorWidget->hasFocus())
+ _colorWidget->setTangentType(eDiscret);
+}
+
+void CurveEditorMainWindow::on_actionTangent_Linear_triggered()
+{
+ if (_curveWidget->hasFocus())
+ _curveWidget->setTangentType(eLinear);
+
+ if (_colorWidget->hasFocus())
+ _colorWidget->setTangentType(eLinear);
+}
+
+void CurveEditorMainWindow::on_actionTangent_Smooth_triggered()
+{
+ if (_curveWidget->hasFocus())
+ _curveWidget->setSmoothTangent();
+
+ if (_colorWidget->hasFocus())
+ _colorWidget->setSmoothTangent();
+}
+
+void CurveEditorMainWindow::on_actionTangent_Ease_Out_triggered()
+{
+ if (_curveWidget->hasFocus())
+ _curveWidget->setEaseOutTangent();
+
+ if (_colorWidget->hasFocus())
+ _colorWidget->setEaseOutTangent();
+}
+
+void CurveEditorMainWindow::on_actionTangent_Ease_In_triggered()
+{
+ if (_curveWidget->hasFocus())
+ _curveWidget->setEaseInTangent();
+
+ if (_colorWidget->hasFocus())
+ _colorWidget->setEaseInTangent();
+}
+
+void CurveEditorMainWindow::on_actionTangent_Spline_triggered()
+{
+ if (_curveWidget->hasFocus())
+ _curveWidget->setTangentType(eCatmullRomSpline);
+
+ if (_colorWidget->hasFocus())
+ _colorWidget->setTangentType(eCatmullRomSpline);
+}
+
+void CurveEditorMainWindow::on_actionSnap_All_triggered()
+{
+ _curveWidget->setSnapAll();
+}
+
+void CurveEditorMainWindow::on_actionSnap_Horizontal_triggered()
+{
+ _curveWidget->setSnapHorizontal();
+}
+
+void CurveEditorMainWindow::on_actionSnap_Vertical_triggered()
+{
+ _curveWidget->setSnapVertical();
+}
+
+void CurveEditorMainWindow::on_actionContract_Horizontally_triggered()
+{
+ _curveWidget->decreaseCurveScaleHorizontally();
+}
+
+void CurveEditorMainWindow::on_actionExpand_Horizontally_triggered()
+{
+ _curveWidget->increaseCurveScaleHorizontally();
+}
+
+void CurveEditorMainWindow::on_actionContract_Vertically_triggered()
+{
+ _curveWidget->decreaseCurveScaleVertically();
+}
+
+void CurveEditorMainWindow::on_actionExpand_Vertically_triggered()
+{
+ _curveWidget->increaseCurveScaleVertically();
+}
+
+void CurveEditorMainWindow::on_actionFrame_Horizontally_triggered()
+{
+ _curveWidget->frameCurveScaleHorizontally();
+}
+
+void CurveEditorMainWindow::on_actionFrame_Vertically_triggered()
+{
+ _curveWidget->frameCurveScaleVertically();
+}
+
+void CurveEditorMainWindow::on_actionFrame_All_triggered()
+{
+ _curveWidget->frameCurveScale();
+}
+
+void CurveEditorMainWindow::on_spinBoxLocation_valueChanged(double value)
+{
+ if (!_updateUIFromData)
+ _curveWidget->setLocation(value);
+}
+
+void CurveEditorMainWindow::on_spinBoxValue_valueChanged(double value)
+{
+ if (!_updateUIFromData)
+ _curveWidget->setValue(value);
+}
+
+void CurveEditorMainWindow::on_btnColor_clicked()
+{
+ QColor color = _colorWidget->getColor();
+ pickColor(color, nullptr);
+ _colorWidget->setColor(color);
+ setButtonColor(ui->btnColor, color);
+}
+
+void CurveEditorMainWindow::on_btnColorTex_clicked()
+{
+ QString filePath = OpenTextureFile(_colorWidget->getColorTex().isEmpty() ? _lastFilePath : _colorWidget->getColorTex());
+ _colorWidget->setColorTex(filePath);
+ setButtonTex(ui->btnColorTex, !filePath.isEmpty());
+
+ if (!filePath.isEmpty())
+ {
+ QFileInfo fileInfo(filePath);
+ _lastFilePath = fileInfo.absoluteDir().absolutePath();
+ }
+}
+
+void CurveEditorMainWindow::on_btnColorReload_clicked()
+{
+ QList<QTreeWidgetItem*> items = ui->treeWidgetColorAttributes->selectedItems();
+ if (0 ==items.count())
+ return;
+
+ _colorWidget->reloadColorTex();
+}
+
+void CurveEditorMainWindow::on_btnColorClear_clicked()
+{
+ _colorWidget->clearColorTex();
+ setButtonTex(ui->btnColorTex, false);
+}
+
+void CurveEditorMainWindow::on_btnAlpha_clicked()
+{
+ int alpha = _colorWidget->getAlpha();
+ pickAlpha(alpha, nullptr);
+ _colorWidget->setAlpha(alpha);
+ setButtonColor(ui->btnAlpha, QColor(alpha, alpha, alpha));
+}
+
+void CurveEditorMainWindow::on_btnAlphaTex_clicked()
+{
+ QString filePath = OpenTextureFile(_colorWidget->getAlphaTex().isEmpty() ? _lastFilePath : _colorWidget->getAlphaTex());
+ _colorWidget->setAlphaTex(filePath);
+ setButtonTex(ui->btnAlphaTex, !filePath.isEmpty());
+
+ if (!filePath.isEmpty())
+ {
+ QFileInfo fileInfo(filePath);
+ _lastFilePath = fileInfo.absoluteDir().absolutePath();
+ }
+}
+
+void CurveEditorMainWindow::on_btnAlphaReload_clicked()
+{
+ QList<QTreeWidgetItem*> items = ui->treeWidgetColorAttributes->selectedItems();
+ if (0 ==items.count())
+ return;
+
+ _colorWidget->reloadAlphaTex();
+}
+
+void CurveEditorMainWindow::on_btnAlphaClear_clicked()
+{
+ _colorWidget->clearAlphaTex();
+ setButtonTex(ui->btnAlphaTex, false);
+}
+
+void CurveEditorMainWindow::on_checkBoxUseAlphaChannellFromColor_stateChanged(int val)
+{
+ _colorWidget->setUseAlphaFromColor(0 != val);
+}
+
+void CurveEditorMainWindow::on_treeWidgetCurveAttributes_itemSelectionChanged()
+{
+ std::vector<CurveAttributeBase*> attributes;
+
+ QList<QTreeWidgetItem*> items = ui->treeWidgetCurveAttributes->selectedItems();
+ int count = items.count();
+ for (int i = 0; i < items.count(); ++i)
+ {
+ CurveAttributeTreeItem* item = static_cast<CurveAttributeTreeItem*>(items.at(i));
+
+ attributes.push_back(item->_attribute);
+
+ qDebug()<< item->_attribute->getName().c_str();
+ }
+
+ _curveWidget->setCurveAttributes(attributes);
+
+ bool canMoveControlPointHorizontally = _canMoveCurveControlPointHorizontally;
+ bool canAddRemoveControlPoint = _canAddRemoveCurveControlPoint;
+ bool canChangeTangentType = _canChangeCurveTangentType;
+ for (size_t i = 0; i < attributes.size(); ++i)
+ {
+ CurveAttributeBase* attribute = attributes[i];
+ if (eGroupAttr == attribute->getType())
+ {
+ CurveAttributeGroup* attributeGroup = static_cast<CurveAttributeGroup*>(attribute);
+ for (size_t j = 0; j < attributeGroup->attributes.size(); ++j)
+ {
+ CurveAttributeBase* attributeInGroup = attributeGroup->attributes[j];
+
+ if (attributeInGroup->canMoveControlPointHorizontally())
+ canMoveControlPointHorizontally = true;
+
+ if (attributeInGroup->canAddRemoveControlPoint())
+ canAddRemoveControlPoint = true;
+
+ if (attributeInGroup->canChangeTangentType())
+ canChangeTangentType = true;
+ }
+ }
+ else
+ {
+ if (attribute->canMoveControlPointHorizontally())
+ canMoveControlPointHorizontally = true;
+
+ if (attribute->canAddRemoveControlPoint())
+ canAddRemoveControlPoint = attribute->canAddRemoveControlPoint();
+
+ if (attribute->canChangeTangentType())
+ canChangeTangentType = true;
+ }
+ }
+
+ ui->spinBoxLocation->setEnabled(canMoveControlPointHorizontally);
+ _syncUIStatusWithSelectedAttribute(canAddRemoveControlPoint, canChangeTangentType);
+}
+
+void CurveEditorMainWindow::on_treeWidgetColorAttributes_itemSelectionChanged()
+{
+ QList<QTreeWidgetItem*> items = ui->treeWidgetColorAttributes->selectedItems();
+ if (0 == items.count())
+ return;
+
+ ColorAttributeTreeItem* item = static_cast<ColorAttributeTreeItem*>(items.at(0));
+ _colorWidget->setColorAttribute(item->_attribute);
+ _colorWidget->setCanAddRemoveControlPoint(item->_attribute->canAddRemoveControlPoint());
+
+ _syncUIStatusWithSelectedAttribute(item->_attribute->canAddRemoveControlPoint(), item->_attribute->canChangeTangentType());
+}
+
+void CurveEditorMainWindow::on_tabWidgetAttributes_currentChanged(int index)
+{
+ //if (eCurveTab == index)
+ //{
+ // _setCurveExclusiveUIEnable(true);
+ //}
+ //else if (eColorTab == index)
+ //{
+ // _setCurveExclusiveUIEnable(false);
+ //}
+}
+
+void CurveEditorMainWindow::on_sliderColorFallOff_sliderMoved(int value)
+{
+ if (!_updateUIFromData)
+ {
+ _colorWidget->setColorFallOff((float)value/100);
+
+ if (_colorWidget->isLink())
+ {
+ _updateUIFromData = true;
+ ui->sliderAlphaFallOff->setValue(value);
+ _updateUIFromData = false;
+ }
+ }
+}
+
+void CurveEditorMainWindow::on_sliderAlphaFallOff_sliderMoved(int value)
+{
+ if (!_updateUIFromData)
+ {
+ _colorWidget->setAlphaFallOff((float)value/100);
+
+ if (_colorWidget->isLink())
+ {
+ _updateUIFromData = true;
+ ui->sliderAlphaFallOff->setValue(value);
+ _updateUIFromData = false;
+ }
+ }
+}
+
+void CurveEditorMainWindow::on_actionAdd_Control_Point_By_Click_triggered(bool val)
+{
+ _curveWidget->setAddCtrlPntByClick(val);
+ _curveWidget->setRemoveCtrlPntByClick(false);
+
+ _colorWidget->setAddCtrlPntByClick(val);
+ _colorWidget->setRemoveCtrlPntByClick(false);
+}
+
+void CurveEditorMainWindow::on_actionRemove_Control_Point_By_Click_triggered(bool val)
+{
+ _curveWidget->setAddCtrlPntByClick(false);
+ _curveWidget->setRemoveCtrlPntByClick(val);
+
+ _colorWidget->setAddCtrlPntByClick(false);
+ _colorWidget->setRemoveCtrlPntByClick(val);
+}
+
+void CurveEditorMainWindow::onCurvePickedControlPointChanged(const std::vector<CurveEntity*>& pickedCurves)
+{
+ bool enableChangeTangentType = true;
+ bool enableAddRemoveCtrlPnts = true;
+ bool enableLoactionEditor = true;
+ bool locationSameForAllAttributes = true;
+ bool valueSameForAllAttributes = true;
+ float location = FLT_MIN, value = FLT_MIN;
+ _updateUIFromData = true;
+ ui->spinBoxLocation->setValue(location);
+ ui->spinBoxValue->setValue(value);
+ _updateUIFromData = false;
+ for(size_t i = 0; i < pickedCurves.size(); ++i)
+ {
+ CurveEntity* curveEntity = pickedCurves[i];
+ std::vector<int>& pickedControlPoints = pickedCurves[i]->getPickedControlPointIndexes();
+ const ControlPoint& ctrlPnt = pickedCurves[i]->_curve->getControlPoint(pickedControlPoints[0]);
+
+ if (!curveEntity->_attribute->canMoveControlPointHorizontally())
+ enableLoactionEditor = false;
+
+ if (pickedControlPoints.size() > 1)
+ enableLoactionEditor = false;
+
+ if (location == FLT_MIN)
+ {
+ location = ctrlPnt.value.x();
+ _updateUIFromData = true;
+ ui->spinBoxLocation->setValue(location);
+ _updateUIFromData = false;
+ }
+ else if (location != ctrlPnt.value.x())
+ locationSameForAllAttributes = false;
+
+ if (value == FLT_MIN)
+ {
+ value = ctrlPnt.value.y();
+ _updateUIFromData = true;
+ ui->spinBoxValue->setValue(value);
+ _updateUIFromData = false;
+ }
+ else if (value != ctrlPnt.value.y())
+ valueSameForAllAttributes = false;
+
+ if (!curveEntity->_attribute->canChangeTangentType() && pickedControlPoints.size() != 0)
+ enableChangeTangentType = false;
+
+ if (!curveEntity->_attribute->canAddRemoveControlPoint() && pickedControlPoints.size() != 0)
+ enableAddRemoveCtrlPnts = false;
+
+ }
+
+ if (pickedCurves.size() > 0)
+ {
+ ui->spinBoxLocation->setEnabled(enableLoactionEditor);
+
+ setFocusColor(ui->labelLoacation, locationSameForAllAttributes);
+ setFocusColor(ui->labelValue, valueSameForAllAttributes);
+
+ _setTangentTypeUIStatus(enableChangeTangentType);
+ _setAddRemoveCtrlPntUIStatus(enableAddRemoveCtrlPnts);
+ }
+ else
+ {
+ on_treeWidgetCurveAttributes_itemSelectionChanged();
+ }
+
+}
+
+void CurveEditorMainWindow::onCurvePickedControlPointValueChanged(QPointF& value)
+{
+ _updateUIFromData = true;
+ ui->spinBoxLocation->setValue(value.x());
+ ui->spinBoxValue->setValue(value.y());
+ _updateUIFromData = false;
+
+ QList<QTreeWidgetItem*> selectedAttributes = ui->treeWidgetCurveAttributes->selectedItems();
+ if (selectedAttributes.count() > 0)
+ {
+
+ }
+}
+
+void CurveEditorMainWindow::_fillCurveAttributesTree()
+{
+ ui->treeWidgetCurveAttributes->clear();
+
+ size_t countAttributes = _curveAttributes.size();
+ for (size_t i = 0; i < countAttributes; ++i)
+ {
+ CurveAttributeBase* attribute = _curveAttributes[i];
+ CurveAttributeTreeItem* itemFirstLevel = new CurveAttributeTreeItem(ui->treeWidgetCurveAttributes, attribute);
+ itemFirstLevel->setText(0, attribute->getName().c_str());
+
+ if (attribute->getType() == eGroupAttr)
+ {
+ CurveAttributeGroup* attributeGroup = static_cast<CurveAttributeGroup*>(attribute);
+ size_t countAttributesInGroup = attributeGroup->attributes.size();
+ for (size_t j = 0; j < countAttributesInGroup; ++j)
+ {
+ CurveAttribute* attributeInGroup = static_cast<CurveAttribute*>(attributeGroup->attributes[j]);
+ CurveAttributeTreeItem* itemSecondLevel = new CurveAttributeTreeItem(itemFirstLevel, attributeInGroup);
+ itemSecondLevel->setText(0, attributeInGroup->getName().c_str());
+ itemSecondLevel->setForeground(0, QBrush(attributeInGroup->color));
+ }
+ }
+ else
+ {
+ CurveAttribute* attributeSecific = static_cast<CurveAttribute*>(attribute);
+ itemFirstLevel->setForeground(0, QBrush(attributeSecific->color));
+ }
+ }
+}
+
+void CurveEditorMainWindow::_fillColorAttributesTree()
+{
+ ui->treeWidgetColorAttributes->clear();
+
+ size_t countAttributes = _colorAttributes.size();
+ for (size_t i = 0; i < countAttributes; ++i)
+ {
+ ColorAttribute* attribute = _colorAttributes[i];
+ ColorAttributeTreeItem* itemFirstLevel = new ColorAttributeTreeItem(ui->treeWidgetColorAttributes, attribute);
+ itemFirstLevel->setText(0, attribute->getName().c_str());
+ }
+}
+
+void CurveEditorMainWindow::_syncUIStatusWithSelectedAttribute(bool canAddRemoveControlPoint, bool canChangeTangentType)
+{
+ _setAddRemoveCtrlPntUIStatus(canAddRemoveControlPoint);
+ _setTangentTypeUIStatus(canChangeTangentType);
+}
+
+void CurveEditorMainWindow::_setCurveExclusiveUIEnable(bool enable)
+{
+ ui->actionSnap_All->setEnabled(enable);
+ ui->actionSnap_Horizontal->setEnabled(enable);
+ ui->actionSnap_Vertical->setEnabled(enable);
+ ui->actionExpand_Horizontally->setEnabled(enable);
+ ui->actionExpand_Vertically->setEnabled(enable);
+ ui->actionFrame_Horizontally->setEnabled(enable);
+ ui->actionFrame_Vertically->setEnabled(enable);
+ ui->actionFrame_All->setEnabled(enable);
+ ui->actionContract_Horizontally->setEnabled(enable);
+ ui->actionContract_Vertically->setEnabled(enable);
+}
+
+void CurveEditorMainWindow::_setColorUIEnable(bool enable)
+{
+ ui->btnColor->setEnabled(enable);
+ ui->btnColorTex->setEnabled(enable);
+ ui->btnColorReload->setEnabled(enable);
+ ui->btnColorClear->setEnabled(enable);
+ ui->sliderColorFallOff->setEnabled(enable);
+}
+
+void CurveEditorMainWindow::_setAlphaUIEnable(bool enable)
+{
+ if (_colorWidget->isLink())
+ ui->btnAlpha->setEnabled(true);
+ else
+ ui->btnAlpha->setEnabled(enable);
+ ui->btnAlphaTex->setEnabled(enable);
+ ui->btnAlphaReload->setEnabled(enable);
+ ui->btnAlphaClear->setEnabled(enable);
+ ui->sliderAlphaFallOff->setEnabled(enable);
+}
+
+void CurveEditorMainWindow::onColorPickedControlPointChanged(bool isColorCtrlPnt)
+{
+ QColor color = _colorWidget->getColor();
+ setButtonColor(ui->btnColor, color);
+ int alpha = _colorWidget->getAlpha();
+ setButtonColor(ui->btnAlpha, QColor(alpha, alpha, alpha));
+
+ QString colorTex = _colorWidget->getColorTex();
+ setButtonTex(ui->btnColorTex, !colorTex.isEmpty());
+ QString alphaTex = _colorWidget->getAlphaTex();
+ setButtonTex(ui->btnAlphaTex, !alphaTex.isEmpty());
+
+ _updateUIFromData = true;
+ ui->sliderColorFallOff->setValue(_colorWidget->getColorFallOff() * 100);
+ ui->sliderAlphaFallOff->setValue(_colorWidget->getAlphaFallOff() * 100);
+ _setColorUIEnable(isColorCtrlPnt);
+ _setAlphaUIEnable(!isColorCtrlPnt);
+ _updateUIFromData = false;
+}
+
+void CurveEditorMainWindow::_saveAttribute(QDomElement& parentElm, CurveAttribute* attribute)
+{
+ QDomElement newElm = parentElm.ownerDocument().createElement(tr("Attribute"));
+ parentElm.appendChild(newElm);
+ newElm.setAttribute(tr("Name"), attribute->getName().c_str());
+ newElm.setAttribute(tr("Color"), QString().setNum(attribute->color.rgba(), 16));
+ if (!ui->checkBoxResamplePoints->isChecked())
+ {
+ _saveCurve(newElm, attribute->curve);
+ }
+ else
+ {
+ _saveCurve(newElm, attribute->curve.resampleCurve(ui->spinBoxResamplePoints->value()));
+ }
+}
+
+void CurveEditorMainWindow::_saveAttribute(QDomElement& parentElm, ColorAttribute* attribute)
+{
+ QDomElement newElm = parentElm.ownerDocument().createElement(tr("Attribute"));
+ parentElm.appendChild(newElm);
+ newElm.setAttribute(tr("Name"), attribute->getName().c_str());
+
+ _saveCurve(newElm, attribute->colorCurve, tr("ColorCurve"));
+ if (attribute->alphaCurve.getControlPointCount() > 0)
+ _saveCurve(newElm, attribute->alphaCurve, tr("AlphaCurve"));
+}
+
+void CurveEditorMainWindow::_saveCurve(QDomElement& parentElm, Curve& curve)
+{
+ QDomDocument domDoc = parentElm.ownerDocument();
+ QDomElement curveElm = domDoc.createElement(tr("Curve"));
+ parentElm.appendChild(curveElm);
+ curveElm.setAttribute(tr("MinValueX"), curve.getMinValue().x());
+ curveElm.setAttribute(tr("MinValueY"), curve.getMinValue().y());
+ curveElm.setAttribute(tr("MaxValueX"), curve.getMaxValue().x());
+ curveElm.setAttribute(tr("MaxValueY"), curve.getMaxValue().y());
+
+ int ctrlPntCount = curve.getControlPointCount();
+ for (int i = 0; i < ctrlPntCount; ++i)
+ {
+ const ControlPoint& ctrlPnt = curve.getControlPoint(i);
+ _saveCtrlPnt(curveElm, ctrlPnt);
+ }
+}
+
+void CurveEditorMainWindow::_saveCurve(QDomElement& parentElm, ColorCurve& curve, const QString& curveName)
+{
+ QDomDocument domDoc = parentElm.ownerDocument();
+ QDomElement curveElm = domDoc.createElement(curveName);
+ parentElm.appendChild(curveElm);
+ curveElm.setAttribute(tr("MinValue"), curve.getMinValue());
+ curveElm.setAttribute(tr("MaxValue"), curve.getMaxValue());
+
+ int ctrlPntCount = curve.getControlPointCount();
+ for (int i = 0; i < ctrlPntCount; ++i)
+ {
+ const ColorControlPoint& ctrlPnt = curve.getControlPoint(i);
+ _saveCtrlPnt(curveElm, ctrlPnt);
+ }
+}
+
+void CurveEditorMainWindow::_saveCtrlPnt(QDomElement& parentElm, const ControlPoint& ctrlPnt)
+{
+ QDomDocument domDoc = parentElm.ownerDocument();
+ QDomElement ctrlPntElm = domDoc.createElement(tr("ControlPoint"));
+ parentElm.appendChild(ctrlPntElm);
+
+ QDomElement valueElm = domDoc.createElement(tr("Value"));
+ ctrlPntElm.appendChild(valueElm);
+ valueElm.setAttribute(tr("X"), ctrlPnt.value.x());
+ valueElm.setAttribute(tr("Y"), ctrlPnt.value.y());
+
+ QDomElement modeElm = domDoc.createElement(tr("InterpolateMode"));
+ ctrlPntElm.appendChild(modeElm);
+ QDomNode txt = domDoc.createTextNode(InterpolateModeToString(ctrlPnt.mode));
+ modeElm.appendChild(txt);
+
+ if (eBezierSpline == ctrlPnt.mode)
+ {
+ QDomElement bezierSplineDataElm = domDoc.createElement(tr("BezierSplineData"));
+ ctrlPntElm.appendChild(bezierSplineDataElm);
+
+ bezierSplineDataElm.setAttribute(tr("InTan"), QString("%0").arg(ctrlPnt.splineData.inTan));
+ bezierSplineDataElm.setAttribute(tr("InLen"), QString("%0").arg(ctrlPnt.splineData.inLen));
+ bezierSplineDataElm.setAttribute(tr("OutTan"), QString("%0").arg(ctrlPnt.splineData.outTan));
+ bezierSplineDataElm.setAttribute(tr("OutLen"), QString("%0").arg(ctrlPnt.splineData.outLen));
+ }
+}
+
+void CurveEditorMainWindow::_saveCtrlPnt(QDomElement& parentElm, const ColorControlPoint& ctrlPnt)
+{
+ QDomDocument domDoc = parentElm.ownerDocument();
+ QDomElement ctrlPntElm = domDoc.createElement(tr("ColorControlPoint"));
+ parentElm.appendChild(ctrlPntElm);
+
+ QDomElement valueElm = domDoc.createElement(tr("Value"));
+ ctrlPntElm.appendChild(valueElm);
+ valueElm.setAttribute(tr("X"), ctrlPnt.x);
+ valueElm.setAttribute(tr("Color"), QString().setNum(ctrlPnt.color.rgba(), 16));
+ valueElm.setAttribute(tr("Weight"), ctrlPnt.weight);
+ valueElm.setAttribute(tr("FallOff"), ctrlPnt.fallOff);
+ valueElm.setAttribute(tr("TexturePath"), ctrlPnt.texturePath.c_str());
+
+ QDomElement modeElm = domDoc.createElement(tr("InterpolateMode"));
+ ctrlPntElm.appendChild(modeElm);
+ QDomNode txt = domDoc.createTextNode(InterpolateModeToString(ctrlPnt.mode));
+ modeElm.appendChild(txt);
+
+ if (eBezierSpline == ctrlPnt.mode)
+ {
+ QDomElement bezierSplineDataElm = domDoc.createElement(tr("BezierSplineData"));
+ ctrlPntElm.appendChild(bezierSplineDataElm);
+
+ bezierSplineDataElm.setAttribute(tr("InTan"), QString("%0").arg(ctrlPnt.splineData.inTan));
+ bezierSplineDataElm.setAttribute(tr("InLen"), QString("%0").arg(ctrlPnt.splineData.inLen));
+ bezierSplineDataElm.setAttribute(tr("OutTan"), QString("%0").arg(ctrlPnt.splineData.outTan));
+ bezierSplineDataElm.setAttribute(tr("OutLen"), QString("%0").arg(ctrlPnt.splineData.outLen));
+ }
+}
+
+CurveAttributeBase* CurveEditorMainWindow::_loadAttribute(QDomElement& elm)
+{
+ QString name = elm.attribute(tr("Name"));
+
+ QDomElement curveElm = elm.firstChildElement(tr("Curve"));
+ if (!curveElm.isNull())
+ {
+ CurveAttribute* attribute = new CurveAttribute("");
+ attribute->_name = name.toStdString();
+ //qDebug()<<"attribute Name"<<name<<" Color:"<<elm.attribute(tr("Color"));
+ attribute->color.setRgba(elm.attribute(tr("Color")).toUInt(0, 16));
+ //qDebug()<<"color:::"<<QString().setNum(attrData->color.rgba(), 16);
+ float minValueX = curveElm.attribute(tr("MinValueX")).toFloat();
+ float minValueY = curveElm.attribute(tr("MinValueY")).toFloat();
+ float maxValueX = curveElm.attribute(tr("MaxValueX")).toFloat();
+ float maxValueY = curveElm.attribute(tr("MaxValueY")).toFloat();
+ attribute->curve.initValueRange(QPointF(minValueX, minValueY), QPointF(maxValueX, maxValueY));
+ _loadCurve(curveElm, attribute->curve);
+
+ return attribute;
+ }
+ else
+ {
+ curveElm = elm.firstChildElement(tr("ColorCurve"));
+
+ if (!curveElm.isNull())
+ {
+ ColorAttribute* attribute = new ColorAttribute("");
+ attribute->_name = name.toStdString();
+ float minValue = curveElm.attribute(tr("MinValue")).toFloat();
+ float maxValue = curveElm.attribute(tr("MaxValue")).toFloat();
+ attribute->colorCurve.initValueRange(minValue, maxValue);
+ _loadCurve(curveElm, attribute->colorCurve);
+
+ curveElm = elm.firstChildElement(tr("AlphaCurve"));
+ minValue = curveElm.attribute(tr("MinValue")).toFloat();
+ maxValue = curveElm.attribute(tr("MaxValue")).toFloat();
+ attribute->alphaCurve.initValueRange(minValue, maxValue);
+ _loadCurve(curveElm, attribute->alphaCurve);
+ return attribute;
+ }
+ }
+
+ return nullptr;
+}
+
+void CurveEditorMainWindow::_loadCurve(QDomElement& elm, Curve& curve)
+{
+ QDomNodeList nodeList = elm.elementsByTagName(tr("ControlPoint"));
+ for (int i = 0; i < nodeList.count(); ++i)
+ {
+ QDomElement ctrlElm = nodeList.at(i).toElement();
+
+ ControlPoint ctrlPnt;
+ if (!ctrlElm.isNull())
+ {
+ _loadCtrlPnt(ctrlElm, ctrlPnt);
+ curve.appendControlPoint(ctrlPnt, false);
+ }
+ }
+}
+
+void CurveEditorMainWindow::_loadCurve(QDomElement& elm, ColorCurve& curve)
+{
+ QDomNodeList nodeList = elm.elementsByTagName(tr("ColorControlPoint"));
+ for (int i = 0; i < nodeList.count(); ++i)
+ {
+ QDomElement ctrlElm = nodeList.at(i).toElement();
+
+ ColorControlPoint ctrlPnt;
+ if (!ctrlElm.isNull())
+ {
+ _loadCtrlPnt(ctrlElm, ctrlPnt);
+ curve.appendControlPoint(ctrlPnt, false);
+ }
+ }
+}
+
+void CurveEditorMainWindow::_loadCtrlPnt(QDomElement& elm, ControlPoint& ctrlPnt)
+{
+ QDomElement valueElm = elm.firstChildElement(tr("Value"));
+ ctrlPnt.value.setX(valueElm.attribute(tr("X")).toFloat());
+ ctrlPnt.value.setY(valueElm.attribute(tr("Y")).toFloat());
+
+ QDomElement modeElm = elm.firstChildElement(tr("InterpolateMode"));
+
+ ctrlPnt.mode = StringToInterpolateMode(modeElm.text());
+
+ if (eBezierSpline == ctrlPnt.mode)
+ {
+ QDomElement bezierElm = elm.firstChildElement(tr("BezierSplineData"));
+
+ ctrlPnt.splineData.inTan = bezierElm.attribute(tr("InTan")).toFloat();
+ ctrlPnt.splineData.inLen = bezierElm.attribute(tr("InLen")).toFloat();
+ ctrlPnt.splineData.outTan = bezierElm.attribute(tr("OutTan")).toFloat();
+ ctrlPnt.splineData.outLen = bezierElm.attribute(tr("OutLen")).toFloat();
+ }
+}
+
+void CurveEditorMainWindow::_loadCtrlPnt(QDomElement& elm, ColorControlPoint& ctrlPnt)
+{
+ QDomElement valueElm = elm.firstChildElement(tr("Value"));
+ ctrlPnt.x = valueElm.attribute(tr("X")).toFloat();
+ ctrlPnt.color.setRgba(valueElm.attribute(tr("Color")).toUInt(0, 16));
+ ctrlPnt.weight = valueElm.attribute(tr("Weight")).toFloat();
+ ctrlPnt.fallOff = valueElm.attribute(tr("FallOff")).toFloat();
+ ctrlPnt.weight = valueElm.attribute(tr("Weight")).toFloat();
+ ctrlPnt.texturePath = valueElm.attribute(tr("TexturePath")).toStdString();
+
+ QDomElement modeElm = elm.firstChildElement(tr("InterpolateMode"));
+
+ ctrlPnt.mode = StringToInterpolateMode(modeElm.text());
+
+ if (eBezierSpline == ctrlPnt.mode)
+ {
+ QDomElement bezierElm = elm.firstChildElement(tr("BezierSplineData"));
+
+ ctrlPnt.splineData.inTan = bezierElm.attribute(tr("InTan")).toFloat();
+ ctrlPnt.splineData.inLen = bezierElm.attribute(tr("InLen")).toFloat();
+ ctrlPnt.splineData.outTan = bezierElm.attribute(tr("OutTan")).toFloat();
+ ctrlPnt.splineData.outLen = bezierElm.attribute(tr("OutLen")).toFloat();
+ }
+}
+
+void CurveEditorMainWindow::_setTangentTypeUIStatus(bool enable)
+{
+ ui->actionTangent_Stepped->setEnabled(enable);
+ ui->actionTangent_Linear->setEnabled(enable);
+ ui->actionTangent_Smooth->setEnabled(enable);
+ ui->actionTangent_Ease_Out->setEnabled(enable);
+ ui->actionTangent_Ease_In->setEnabled(enable);
+ ui->actionTangent_Spline->setEnabled(enable);
+}
+
+void CurveEditorMainWindow::_setAddRemoveCtrlPntUIStatus(bool enable)
+{
+ ui->actionAdd_Before_Selected->setEnabled(enable);
+ ui->actionAdd_After_Selected->setEnabled(enable);
+ ui->actionRemove_Selected->setEnabled(enable);
+ ui->actionAdd_Control_Point_By_Click->setEnabled(enable);
+ ui->actionRemove_Control_Point_By_Click->setEnabled(enable);
+}
+
+} // namespace CurveEditor
+} // namespace nvidia \ No newline at end of file
diff --git a/tools/CurveEditor/source/Internal/Window/CurveWidget.cpp b/tools/CurveEditor/source/Internal/Window/CurveWidget.cpp
new file mode 100644
index 0000000..fc778e5
--- /dev/null
+++ b/tools/CurveEditor/source/Internal/Window/CurveWidget.cpp
@@ -0,0 +1,1229 @@
+#include "CurveWidget.h"
+
+#include <QtWidgets/QLabel>
+#include <QtGui/QImage>
+#include <QtWidgets/QVBoxLayout>
+#include <QtGui/QMouseEvent>
+#include <QtGui/QPaintEvent>
+#include <QtGui/QPainter>
+#include <QtGui/QPainterPath>
+#include <QtCore/QDebug>
+#include "CurveEditorMainWindow.h"
+
+namespace nvidia {
+namespace CurveEditor {
+
+const int MARGIN_X = 2;
+const int MARGIN_Y = 2;
+const int SNAP_DISTANCE = 5;
+const float CROSS_THRESHOLD = 5.0f;
+const int GRID_INTIAL_SEGMENT_COUNT = 4;
+const int CTRL_PNT_ICON_SIZE = 6;
+const int CLICK_ON_CURVE_THRESHOLD = 4;
+const int CURVE_WIDTH = 2;
+const QColor GRID_COLOR = QColor(32, 32, 32, 64);
+
+//////////////////////////////////////////////////////////////////////////////
+QPointF NDCToScreenCoord(QWidget* pWidget, QPointF p)
+{
+ int w = pWidget->width();
+ int h = pWidget->height();
+
+ float x = MARGIN_X + p.x() * (w - MARGIN_X * 2.0f);
+ float y = h - MARGIN_Y * 2.0 + p.y() * (MARGIN_Y * 3.0f - h);
+
+ return QPointF(x, y);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+QPointF ScreenToNDC(QWidget* pWidget, QPointF p)
+{
+ int w = pWidget->width();
+ int h = pWidget->height();
+
+ float sizey = 1.0f - 2.0f * MARGIN_Y;
+
+ float x = (p.x() - MARGIN_X) / (2 - MARGIN_X * 2.0f);
+ float y = (MARGIN_Y * 2.0f + p.y() - h) / (MARGIN_Y * 3.0f - h);
+
+ return QPointF(x, y);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool IsInSelectedCtrlPnts(const std::vector<int>& pickedPoints, int pointIndex)
+{
+ for (std::vector<int>::const_iterator itr = pickedPoints.begin(); itr != pickedPoints.end(); ++itr)
+ {
+ if (*itr == pointIndex)
+ return true;
+ }
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool IsSamePoint(const QPointF& pntA, const QPointF& pntB, int threshold)
+{
+ float dx = pntB.x() - pntA.x();
+ float dy = pntB.y() - pntA.y();
+
+ float r = sqrt(dx * dx + dy * dy);
+ if (r <= threshold)
+ return true;
+ else
+ return false;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+int FindSelectedCtrlPnt(const std::vector<QPointF>& points, const QPointF& pickPos)
+{
+ for (size_t i = 0; i < points.size(); i++)
+ {
+ if (IsSamePoint(points[i], pickPos, CTRL_PNT_ICON_SIZE/2))
+ return (int)i;
+ }
+ return -1;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+CurveEntity::CurveEntity(CurveWidget* holder, CurveAttribute* attribute, const QColor& color)
+ : _holder(holder)
+ , _attribute(attribute)
+ , _curve(&(attribute->curve))
+ , _color(color)
+ , _pickedPoint(-1)
+ , _pickedPoints()
+ , _lastMousePosScreen()
+ , _ctrlPntToRemove(-1)
+{
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::setLocation(float location)
+{
+ if (_pickedPoints.size() != 1)
+ return ;
+
+ ControlPoint pnt = _curve->getControlPoint(_pickedPoints[0]);
+ pnt.value.setX(location);
+ _curve->setControlPoint(_pickedPoints[0], pnt);
+ emit _holder->CurveAttributeChanged(_attribute);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::setValue(float value)
+{
+ if (_pickedPoints.size() != 1)
+ return ;
+
+ ControlPoint pnt = _curve->getControlPoint(_pickedPoints[0]);
+ pnt.value.setY(value);
+ _curve->setControlPoint(_pickedPoints[0], pnt);
+ emit _holder->CurveAttributeChanged(_attribute);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::addControlPointsBeforeSelected()
+{
+ bool update = false;
+ for (std::vector<int>::iterator itr = _pickedPoints.begin(); itr != _pickedPoints.end(); ++itr)
+ {
+ if (*itr == 0)
+ continue;
+
+ _curve->insertControlPointAt(*itr);
+ ++(*itr);
+ update = true;
+
+ if (*itr <= _pickedPoint)
+ {
+ ++_pickedPoint;
+ }
+
+ for (std::vector<int>::iterator itrRight = itr + 1; itrRight != _pickedPoints.end(); ++itrRight)
+ {
+ ++(*itrRight);
+ }
+ }
+
+ if (update)
+ {
+ _curve->_needSample = true;
+ emit _holder->CurveAttributeChanged(_attribute);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::addControlPointsAfterSelected()
+{
+ bool update = false;
+ for (std::vector<int>::iterator itr = _pickedPoints.begin(); itr != _pickedPoints.end(); ++itr)
+ {
+ _curve->insertControlPointAt(*itr + 1);
+ update = true;
+
+ if ((*itr + 1) < _pickedPoint)
+ {
+ ++_pickedPoint;
+ }
+
+ for (std::vector<int>::iterator itrRight = itr + 1; itrRight != _pickedPoints.end(); ++itrRight)
+ {
+ ++(*itrRight);
+ }
+ }
+
+ if (update)
+ {
+ _curve->_needSample = true;
+ emit _holder->CurveAttributeChanged(_attribute);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::removeSelectedControlPoints()
+{
+ if (_pickedPoints.size() > 0)
+ {
+ _curve->removeControlPoints(_pickedPoints);
+ _pickedPoints.clear();
+ _pickedPoint = -1;
+ _curve->_needSample = true;
+ emit _holder->CurveAttributeChanged(_attribute);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::setTangentType(InterpolateMode mode)
+{
+ size_t pointsCount = _curve->getControlPointCount();
+ for (int i = 0; i < pointsCount; i++)
+ {
+ if (IsInSelectedCtrlPnts(_pickedPoints, i))
+ {
+ ControlPoint ctrlPnt = _curve->getControlPoint(i);
+ ctrlPnt.mode = mode;
+ _curve->setControlPoint(i, ctrlPnt);
+ emit _holder->CurveAttributeChanged(_attribute);
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::setSmoothTangent()
+{
+ size_t pointsCount = _curve->getControlPointCount();
+ for (int i = 0; i < pointsCount; i++)
+ {
+ if (IsInSelectedCtrlPnts(_pickedPoints, i) && i != pointsCount - 1)
+ {
+ ControlPoint ctrlctrlPntFront = _curve->getControlPoint(i);
+ ctrlctrlPntFront.mode = eBezierSpline;
+ ctrlctrlPntFront.splineData.outLen = 1.0;
+ ctrlctrlPntFront.splineData.outTan = 0;
+ _curve->setControlPoint(i, ctrlctrlPntFront);
+
+ ControlPoint ctrlPntBehiand = _curve->getControlPoint(i + 1);
+ ctrlPntBehiand.mode = eBezierSpline;
+ ctrlPntBehiand.splineData.inLen = 1.0;
+ ctrlPntBehiand.splineData.inTan = 0.0;
+ _curve->setControlPoint(i + 1, ctrlPntBehiand);
+
+ emit _holder->CurveAttributeChanged(_attribute);
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::setEaseInTangent()
+{
+ size_t pointsCount = _curve->getControlPointCount();
+ for (int i = 0; i < pointsCount; i++)
+ {
+ if (IsInSelectedCtrlPnts(_pickedPoints, i) && i != pointsCount - 1)
+ {
+ ControlPoint ctrlctrlPntFront = _curve->getControlPoint(i);
+ ctrlctrlPntFront.mode = eBezierSpline;
+ ctrlctrlPntFront.splineData.outLen = 0.0;
+ ctrlctrlPntFront.splineData.outTan = 0;
+ _curve->setControlPoint(i, ctrlctrlPntFront);
+
+ ControlPoint ctrlPntBehiand = _curve->getControlPoint(i + 1);
+ ctrlPntBehiand.mode = eBezierSpline;
+ ctrlPntBehiand.splineData.inLen = 1.0;
+ ctrlPntBehiand.splineData.inTan = 0;
+ _curve->setControlPoint(i + 1, ctrlPntBehiand);
+
+ emit _holder->CurveAttributeChanged(_attribute);
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::setEaseOutTangent()
+{
+ size_t pointsCount = _curve->getControlPointCount();
+ for (int i = 0; i < pointsCount; i++)
+ {
+ if (IsInSelectedCtrlPnts(_pickedPoints, i) && i != pointsCount - 1)
+ {
+ ControlPoint ctrlctrlPntFront = _curve->getControlPoint(i);
+ ctrlctrlPntFront.mode = eBezierSpline;
+ ctrlctrlPntFront.splineData.outLen = 1.0;
+ ctrlctrlPntFront.splineData.outTan = 0;
+ _curve->setControlPoint(i, ctrlctrlPntFront);
+
+ ControlPoint ctrlPntBehiand = _curve->getControlPoint(i + 1);
+ ctrlPntBehiand.mode = eBezierSpline;
+ ctrlPntBehiand.splineData.inLen = 0.0;
+ ctrlPntBehiand.splineData.inTan = 0;
+ _curve->setControlPoint(i + 1, ctrlPntBehiand);
+
+ emit _holder->CurveAttributeChanged(_attribute);
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+int CurveEntity::getControlPointCount()
+{
+ return _curve->getControlPointCount();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+QRectF CurveEntity::getBoundingBox()
+{
+ return QRectF(_curve->getMinValue(), _curve->getMaxValue());
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::mousePressEvent( QMouseEvent* e, bool& pickedPoint)
+{
+ if (!(e->modifiers() & Qt::ControlModifier))
+ {
+ _pickedPoints.clear();
+ }
+
+ std::vector<QPointF> points;
+ _makePoints(points);
+ QPoint mousePos = e->pos();
+ _lastMousePosScreen = mousePos;
+
+ _pickedPoint = FindSelectedCtrlPnt(points, mousePos);
+ if (-1 != _pickedPoint)
+ {
+ if (_holder->_canRemoveCtrlPntByClick && _attribute->canAddRemoveControlPoint())
+ {
+ _curve->removeControlPoint(_pickedPoint);
+ _pickedPoint = -1;
+ return;
+ }
+ pickedPoint = true;
+ }
+ else
+ {
+ if (_holder->_canAddCtrlPntByClick)
+ {
+ _addCtrlPntByClick(mousePos);
+ }
+ return ;
+ }
+
+ std::vector<int>::iterator itr = _pickedPoints.begin();
+ for (; itr != _pickedPoints.end(); ++itr)
+ {
+ if (*itr == _pickedPoint)
+ break;
+ else if (*itr > _pickedPoint)
+ {
+ itr = _pickedPoints.insert(itr, _pickedPoint);
+ break;
+ }
+ }
+
+ if (itr == _pickedPoints.end())
+ {
+ _pickedPoints.insert(itr, _pickedPoint);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::mouseReleaseEvent( QMouseEvent* e )
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::mouseMoveEvent( QMouseEvent* e )
+{
+ Qt::MouseButton buttons = e->button();
+
+ {
+ //if (_pickedPoint >= 0)
+ QPointF mousePosScreen = e->pos();
+ QPointF deltaPosScreen = mousePosScreen - _lastMousePosScreen;
+ QPointF destinationPosScreen = mousePosScreen;
+ _lastMousePosScreen = mousePosScreen;
+ std::vector<int>::iterator itr = _pickedPoints.begin();
+ for (; itr != _pickedPoints.end(); ++itr)
+ {
+ int pickedPoint = *itr;
+ ControlPoint pickedCtrlPnt = _curve->getControlPoint(pickedPoint);
+ QPointF ctrlPntLastScreenPos = _holder->_valueToScreen(pickedCtrlPnt.value);
+
+ destinationPosScreen = ctrlPntLastScreenPos + deltaPosScreen;
+ destinationPosScreen = _holder->_getSnapSreenPos(destinationPosScreen);
+
+ if (!_attribute->canMoveControlPointHorizontally())
+ destinationPosScreen.setX(ctrlPntLastScreenPos.x());
+ else
+ {
+ // make sure this picked control point not move accross other control point
+ if (pickedPoint == 0)
+ {
+ QPointF nextCtrlPntScreenPos = _holder->_valueToScreen(_curve->getControlPoint(pickedPoint + 1).value);
+ if (destinationPosScreen.x() > (nextCtrlPntScreenPos.x() - CROSS_THRESHOLD))
+ destinationPosScreen.setX(nextCtrlPntScreenPos.x() - CROSS_THRESHOLD);
+ }
+ else if (pickedPoint == (_curve->getControlPointCount() - 1) )
+ {
+ QPointF fomerCtrlPntScreenPos = _holder->_valueToScreen(_curve->getControlPoint(pickedPoint - 1).value);
+ if (destinationPosScreen.x() < (fomerCtrlPntScreenPos.x() + CROSS_THRESHOLD))
+ destinationPosScreen.setX(fomerCtrlPntScreenPos.x() + CROSS_THRESHOLD);
+ }
+ else
+ {
+ QPointF fomerCtrlPntScreenPos = _holder->_valueToScreen(_curve->getControlPoint(pickedPoint - 1).value);
+ QPointF nextCtrlPntScreenPos = _holder->_valueToScreen(_curve->getControlPoint(pickedPoint + 1).value);
+ if (destinationPosScreen.x() < (fomerCtrlPntScreenPos.x() + CROSS_THRESHOLD))
+ destinationPosScreen.setX(fomerCtrlPntScreenPos.x() + CROSS_THRESHOLD);
+ if (destinationPosScreen.x() > (nextCtrlPntScreenPos.x() - CROSS_THRESHOLD))
+ destinationPosScreen.setX(nextCtrlPntScreenPos.x() - CROSS_THRESHOLD);
+ }
+ }
+
+ QPointF p = _holder->_screenToValue(destinationPosScreen);
+
+ QPointF min = _curve->getMinValue();
+ QPointF max = _curve->getMaxValue();
+
+ //make control point move in value range
+ {
+ if (p.x() < min.x())
+ p.setX(min.x());
+ else if (p.x() > max.x())
+ p.setX(max.x());
+
+ if (p.y() < min.y())
+ p.setY(min.y());
+ else if (p.y() > max.y())
+ p.setY(max.y());
+ }
+
+ pickedCtrlPnt.value = p;
+ _curve->setControlPoint(pickedPoint, pickedCtrlPnt);
+ emit _holder->PickedControlPointValueChanged(p);
+
+ emit _holder->CurveAttributeChanged(_attribute);
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::draw(QPainter &painter)
+{
+ std::vector<QPointF> points;
+ _makePoints(points);
+
+ _drawCurve(painter);
+
+ _drawPoints(points, painter, _pickedPoints);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::_drawCurve(QPainter &painter)
+{
+ painter.save();
+
+ {
+ QPen pen( Qt::black );
+ pen.setColor(_color);
+ pen.setWidth(CURVE_WIDTH);
+ pen.setStyle(Qt::SolidLine);
+
+ painter.setPen(pen);
+ painter.setRenderHint(QPainter::Antialiasing, false);
+ }
+
+ QPainterPath path;
+
+ std::vector<QPointF> samplePoints = _curve->getSamplePoints();
+ path.moveTo(_holder->_valueToScreen(samplePoints[0]));
+
+ for (size_t i = 0; i < samplePoints.size(); ++i)
+ {
+ path.lineTo(_holder->_valueToScreen(samplePoints[i]));
+ }
+ painter.drawPath(path);
+
+ painter.restore();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::_makePoints(std::vector<QPointF>& points)
+{
+ size_t ctrlPntsCount = _curve->getControlPointCount();
+ for (int i = 0; i < ctrlPntsCount; i++)
+ points.push_back( _holder->_valueToScreen(_curve->getControlPoint(i).value) );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::_drawPoints(const std::vector<QPointF>& points, QPainter &painter, const std::vector<int>& pickedPoints)
+{
+ {
+ QPen pen( Qt::black );
+ pen.setColor(QColor(255,255,255));
+ pen.setWidth(6);
+ pen.setStyle(Qt::SolidLine);
+
+ painter.setPen(pen);
+ painter.setRenderHint(QPainter::Antialiasing, false);
+ }
+
+ for (int i = 0; i < points.size(); i++)
+ {
+ QPen pen( Qt::black );
+ pen.setWidth(CTRL_PNT_ICON_SIZE);
+ pen.setStyle(Qt::SolidLine);
+
+ if (IsInSelectedCtrlPnts(pickedPoints,i))
+ pen.setColor(QColor(255,0,0));
+ else
+ pen.setColor(QColor(255,255,255));
+
+ painter.setPen(pen);
+ painter.drawPoint( points[i] );
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveEntity::_addCtrlPntByClick(const QPointF& mouseScreenPos)
+{
+ if (!_attribute->canAddRemoveControlPoint())
+ return ;
+
+ QPointF pos= _holder->_screenToValue(mouseScreenPos);
+
+ QPointF pntOnCurve = _curve->getPointByX(pos.x());
+ QPointF pntOnCurveScreen = _holder->_valueToScreen(pntOnCurve);
+
+ if ( IsSamePoint(mouseScreenPos, pntOnCurveScreen, CLICK_ON_CURVE_THRESHOLD) )
+ {
+ _pickedPoint = _curve->appendControlPoint(pntOnCurve.x());
+ _holder->update();
+ }
+
+}
+
+//////////////////////////////////////////////////////////////////////////////
+bool CurveEntity::_canRemoveCtrlPntByRightClick(const QPointF& mouseScreenPos)
+{
+ std::vector<QPointF> points;
+ _makePoints(points);
+
+ _ctrlPntToRemove = FindSelectedCtrlPnt(points, mouseScreenPos);
+
+ if ( !_attribute->canAddRemoveControlPoint()
+ || (-1 == _ctrlPntToRemove)
+ || 2 == _curve->_controlPoints.size() && -1 != _ctrlPntToRemove)
+ {
+ return false;
+ }
+ else
+ return true;
+}
+
+void CurveEntity::_removeCtrlPntByRightClick()
+{
+ if (-1 != _ctrlPntToRemove && _attribute->canAddRemoveControlPoint())
+ {
+ _curve->removeControlPoint(_ctrlPntToRemove);
+ }
+ _ctrlPntToRemove = -1;
+ _pickedPoint = -1;
+ _pickedPoints.clear();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+CurveWidget::CurveWidget(QWidget* parent)
+ : QFrame(parent)
+ , _parent(parent)
+ , _moveCrossOtherCtrlPnt(false)
+ , _moveCtrlPnt(false)
+ , _pan(false)
+ , _snapHorizontal(false)
+ , _snapVertical(false)
+ , _canAddCtrlPntByClick(false)
+ , _canRemoveCtrlPntByClick(false)
+ , _curveFitWindowScale(1.0, 1.0)
+ , _curveFitWindowOffset(0.0, 0.0)
+ , _curveScaleLevel(1.0, 1.0)
+ , _contextMenu(nullptr)
+ , _removeCtrlPntAction(nullptr)
+{
+ setFocusPolicy(Qt::ClickFocus );
+ //QString focusStyle = QString("QFrame:focus { border:1px solid #FF0000; }");
+ //setStyleSheet(focusStyle);
+
+ setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(onShowContextMenu(const QPoint&)));
+
+ _contextMenu = new QMenu(this);;
+ _removeCtrlPntAction = new QAction(this);
+ _removeCtrlPntAction->setText(tr("Remove Control Point"));
+ _contextMenu->addAction(_removeCtrlPntAction);
+
+ connect(_removeCtrlPntAction, SIGNAL(triggered()), this, SLOT(onRemoveControlPoint()) );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::onShowContextMenu(const QPoint& pos)
+{
+ bool enableRemoveCtrlPntAction = false;
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ if (curveEntity._canRemoveCtrlPntByRightClick(pos))
+ enableRemoveCtrlPntAction = true;
+ }
+
+ _removeCtrlPntAction->setEnabled(enableRemoveCtrlPntAction);
+ _contextMenu->exec(QCursor::pos());
+}
+
+void CurveWidget::onRemoveControlPoint()
+{
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ curveEntity._removeCtrlPntByRightClick();
+ }
+
+ std::vector<CurveEntity*> pickedCurves;
+ emit PickedControlPointChanged(pickedCurves);
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::paintEvent(QPaintEvent * e)
+{
+ QFrame::paintEvent(e);
+
+ QPainter painter(this);
+ painter.setRenderHints(QPainter::Antialiasing, true);
+
+ _drawGrid(painter);
+
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ curveEntity.draw(painter);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::resizeEvent(QResizeEvent* e)
+{
+ _updateCurveFitWindowPara();
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::mousePressEvent( QMouseEvent* e )
+{
+ if (e->buttons() == Qt::MiddleButton)
+ {
+ setCursor(Qt::OpenHandCursor);
+ _mousePressScreenPos = QPointF(e->pos().x(), e->pos().y());
+ _pan = true;
+ }
+ else
+ {
+ std::vector<CurveEntity*> pickedCurves;
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ curveEntity.mousePressEvent(e, _moveCtrlPnt);
+ if (curveEntity.getPickedControlPointIndexes().size() > 0)
+ pickedCurves.push_back(&curveEntity);
+ }
+
+ emit PickedControlPointChanged(pickedCurves);
+
+ update();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::mouseReleaseEvent( QMouseEvent* e )
+{
+ if (_moveCtrlPnt)
+ {
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ curveEntity.mouseReleaseEvent(e);
+ }
+ }
+ else if (_pan)
+ {
+ setCursor(Qt::ArrowCursor);
+ _curOrinScreenPos = _lastOrinScreenPos + (QPointF(e->pos().x() - _mousePressScreenPos.x(), _mousePressScreenPos.y() - e->pos().y()));
+ _lastOrinScreenPos = _curOrinScreenPos;
+ _updateCurveFitWindowPara();
+
+ }
+
+ _moveCtrlPnt = false;
+ _pan = false;
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::mouseMoveEvent( QMouseEvent* e )
+{
+ if (_moveCtrlPnt)
+ {
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ curveEntity.mouseMoveEvent(e);
+ }
+ }
+ else if (e->buttons() & Qt::MiddleButton)
+ {
+ _curOrinScreenPos = _lastOrinScreenPos + (QPointF(e->pos().x() - _mousePressScreenPos.x(), _mousePressScreenPos.y() - e->pos().y()));
+ _updateCurveFitWindowPara();
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::wheelEvent(QWheelEvent *e)
+{
+ int numDegrees = e->delta() / 8;
+
+ float zoom = 1.0 + numDegrees / 360.0f;
+ _curveScaleLevel.setX(_curveScaleLevel.x() * zoom);
+ _curveScaleLevel.setY(_curveScaleLevel.y() * zoom);
+
+ _updateCurveFitWindowPara();
+ update();
+ e->accept();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::keyPressEvent(QKeyEvent *e)
+{
+ bool move = false;
+ switch(e->key())
+ {
+ case Qt::Key_Left:
+ _curOrinScreenPos = _lastOrinScreenPos + QPointF(-1.0f, 0.0f);
+ _lastOrinScreenPos = _curOrinScreenPos;
+ move = true;
+ break;
+ case Qt::Key_Up:
+ _curOrinScreenPos = _lastOrinScreenPos + QPointF(0.0f, 1.0f);
+ _lastOrinScreenPos = _curOrinScreenPos;
+ move = true;
+ break;
+ case Qt::Key_Right:
+ _curOrinScreenPos = _lastOrinScreenPos + QPointF(1.0f, 0.0f);
+ _lastOrinScreenPos = _curOrinScreenPos;
+ move = true;
+ break;
+ case Qt::Key_Down:
+ _curOrinScreenPos = _lastOrinScreenPos + QPointF(0.0f, -1.0f);
+ _lastOrinScreenPos = _curOrinScreenPos;
+ move = true;
+ break;
+ }
+
+ if (move)
+ {
+ _updateCurveFitWindowPara();
+ update();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::setLocation(float location)
+{
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ curveEntity.setLocation(location);
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::setValue(float value)
+{
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ curveEntity.setValue(value);
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::setCurveAttributes(std::vector<CurveAttributeBase*> attributes)
+{
+ _curves.clear();
+
+ for (std::vector<CurveAttributeBase*>::iterator itr = attributes.begin(); itr != attributes.end(); ++itr)
+ {
+ CurveAttributeBase* attribute = *itr;
+ if (attribute->getType() == eSingleAttr)
+ {
+ CurveAttribute* attributeSpecific = static_cast<CurveAttribute*>(attribute);
+
+ CurveEntity curveEntity(this, attributeSpecific, attributeSpecific->color);
+ _curves.push_back(curveEntity);
+ }
+ else if (attribute->getType() == eGroupAttr)
+ {
+ CurveAttributeGroup* attributeGroup = static_cast<CurveAttributeGroup*>(attribute);
+ size_t countAttributesInGroup = attributeGroup->attributes.size();
+ for (size_t i = 0; i < countAttributesInGroup; ++i)
+ {
+ CurveAttribute* attributeInGroup = attributeGroup->attributes[i];
+
+ CurveEntity curveEntity(this, attributeInGroup, attributeInGroup->color);
+ _curves.push_back(curveEntity);
+ }
+ }
+ }
+
+ _updateCurveFitWindowPara();
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::reset()
+{
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ curveEntity._attribute->curve.reset();
+ emit CurveAttributeChanged(curveEntity._attribute);
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::addControlPointsBeforeSelected()
+{
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ curveEntity.addControlPointsBeforeSelected();
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::addControlPointsAfterSelected()
+{
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ curveEntity.addControlPointsAfterSelected();
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::removeSelectedControlPoints()
+{
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ curveEntity.removeSelectedControlPoints();
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::setTangentType(InterpolateMode mode)
+{
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ curveEntity.setTangentType(mode);
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::setSmoothTangent()
+{
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ curveEntity.setSmoothTangent();
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::setEaseInTangent()
+{
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ curveEntity.setEaseInTangent();
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::setEaseOutTangent()
+{
+ size_t curveCount = _curves.size();
+ for (size_t i = 0; i < curveCount; ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+ curveEntity.setEaseOutTangent();
+ }
+
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::increaseCurveScaleHorizontally()
+{
+ _curveScaleLevel.setX(_curveScaleLevel.x() * 2);
+ _updateCurveFitWindowPara();
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::decreaseCurveScaleHorizontally()
+{
+ _curveScaleLevel.setX(_curveScaleLevel.x() / 2);
+ _updateCurveFitWindowPara();
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::increaseCurveScaleVertically()
+{
+ _curveScaleLevel.setY(_curveScaleLevel.y() * 2);
+ _updateCurveFitWindowPara();
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::decreaseCurveScaleVertically()
+{
+ _curveScaleLevel.setY(_curveScaleLevel.y() / 2);
+ _updateCurveFitWindowPara();
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::frameCurveScaleHorizontally()
+{
+ _curveScaleLevel.setX(1.0f);
+ _curOrinScreenPos.setX(0);
+ _lastOrinScreenPos.setX(0);
+ _updateCurveFitWindowPara();
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::frameCurveScaleVertically()
+{
+ _curveScaleLevel.setY(1.0f);
+ _curOrinScreenPos.setY(0);
+ _lastOrinScreenPos.setY(0);
+ _updateCurveFitWindowPara();
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::frameCurveScale()
+{
+ _curveScaleLevel.setX(1.0f);
+ _curveScaleLevel.setY(1.0f);
+ _curOrinScreenPos = QPointF(0,0);
+ _lastOrinScreenPos = QPointF(0,0);
+ _updateCurveFitWindowPara();
+ update();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::_updateCurveFitWindowPara()
+{
+ QRect winSize = rect();
+
+ float minX = 0;
+ float minY = 0;
+ float maxX = 0;
+ float maxY = 0;
+
+ for (size_t i = 0; i < _curves.size(); ++i)
+ {
+ CurveEntity& curveEntity = _curves[i];
+
+ QRectF boundingBox = curveEntity.getBoundingBox();
+
+ if (minX > boundingBox.x())
+ minX = boundingBox.x();
+
+ if (minY > boundingBox.y())
+ minY = boundingBox.y();
+
+ if (maxX < boundingBox.right())
+ maxX = boundingBox.right();
+
+ if (maxY < boundingBox.bottom())
+ maxY = boundingBox.bottom();
+ }
+
+ float curveWidth = maxX - minX;
+ float curveHeight = maxY - minY;
+
+ if (0 == curveWidth && 0 == curveHeight)
+ {
+ curveWidth = 1.0;
+ curveHeight = 1.0;
+ }
+ else if (0 == curveWidth)
+ {
+ curveWidth = curveHeight;
+ }
+ else if (0 == curveHeight)
+ {
+ curveHeight = curveWidth;
+ }
+
+ float widthScale = (winSize.width() - MARGIN_X * 2.0f) / curveWidth;
+ float heightScale = (MARGIN_Y * 2.0f - winSize.height()) / curveHeight;
+ _curveFitWindowScale = QPointF(widthScale, heightScale);
+
+ float widthOffset = MARGIN_X + _curOrinScreenPos.x() - minX * widthScale * _curveScaleLevel.x();
+ float heightOffset = (winSize.height() - MARGIN_Y - _curOrinScreenPos.y())- minY * heightScale * _curveScaleLevel.y();
+ _curveFitWindowOffset = QPointF(widthOffset, heightOffset);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+QPointF CurveWidget::_valueToScreen(const QPointF& pnt)
+{
+ QPointF curveScale = QPointF(_curveFitWindowScale.x() * _curveScaleLevel.x(), _curveFitWindowScale.y() * _curveScaleLevel.y());
+
+ float x = pnt.x() * curveScale.x() + _curveFitWindowOffset.x();
+ float y = pnt.y() * curveScale.y() + _curveFitWindowOffset.y();
+ return QPointF(x, y);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+QPointF CurveWidget::_screenToValue(const QPointF& pnt)
+{
+ QPointF curveScale = QPointF(_curveFitWindowScale.x() * _curveScaleLevel.x(), _curveFitWindowScale.y() * _curveScaleLevel.y());
+
+ float x = (pnt.x() - _curveFitWindowOffset.x()) / curveScale.x();
+ float y = (pnt.y() - _curveFitWindowOffset.y()) / curveScale.y();
+
+ return QPointF(x, y);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::_drawAxis(QPainter &painter)
+{
+ painter.save();
+ {
+ QPen pen( Qt::black );
+ pen.setColor(GRID_COLOR);
+ pen.setWidth(2);
+ pen.setStyle(Qt::SolidLine);
+
+ painter.setPen(pen);
+ painter.setRenderHint(QPainter::Antialiasing, false);
+ }
+
+ {
+ int w = width() - MARGIN_X * 2;
+ int h = height() - MARGIN_Y * 2;
+
+ QPainterPath path;
+
+ QPointF x = _dragedCoordinateToScreen(QPointF(w, 0));
+ QPointF y = _dragedCoordinateToScreen(QPointF(0, h));
+
+ path.moveTo(_dragedCoordinateToScreen(QPointF(0, 0)));
+ path.lineTo(x);
+ path.moveTo(_dragedCoordinateToScreen(QPointF(0, 0)));
+ path.lineTo(y);
+
+ painter.drawPath(path);
+ }
+
+ painter.restore();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+void CurveWidget::_drawGrid(QPainter &painter)
+{
+ painter.save();
+ {
+ QPen pen( Qt::black );
+ pen.setColor(GRID_COLOR);
+ pen.setWidth(1);
+ pen.setStyle(Qt::SolidLine);
+
+ painter.setPen(pen);
+ painter.setRenderHint(QPainter::Antialiasing, false);
+ }
+
+ {
+ QPainterPath path;
+
+ int w = width() - MARGIN_X * 2;
+ int h = height() - MARGIN_Y * 2;
+
+ QPointF newOri = _dragedCoordinateToScreen(_curOrinScreenPos);
+
+ float width = w;
+ float height = h;
+ int gridXSegmentCount = GRID_INTIAL_SEGMENT_COUNT / _curveScaleLevel.x();
+ int gridYSegmentCount = GRID_INTIAL_SEGMENT_COUNT / _curveScaleLevel.y();
+
+ if (_curveScaleLevel.x() > 1)
+ {
+ width = w * _curveScaleLevel.x();
+ gridXSegmentCount *= _curveScaleLevel.x();
+ }
+
+ if (_curveScaleLevel.y() > 1)
+ {
+ height = h * _curveScaleLevel.y();
+ gridYSegmentCount *= _curveScaleLevel.y();
+ }
+
+ // draw horizontal lines
+ for (int i = 0 - gridXSegmentCount; i <= gridXSegmentCount * 2; ++i)
+ {
+ QPointF bottom = _dragedCoordinateToScreen(QPointF(width * i / (float)gridXSegmentCount, -height));
+ QPointF up = _dragedCoordinateToScreen(QPointF(width * i / (float)gridXSegmentCount, height * 2));
+ path.moveTo(bottom);
+ path.lineTo(up);
+
+ painter.drawPath(path);
+ }
+
+ // draw vertical lines
+ for (int i = 0 - gridYSegmentCount; i <= gridYSegmentCount * 2; ++i)
+ {
+ QPointF left = _dragedCoordinateToScreen(QPointF(-width, i * height / (float)gridYSegmentCount));
+ QPointF right = _dragedCoordinateToScreen(QPointF(2 * width, i * height / (float)gridYSegmentCount));
+ path.moveTo(left);
+ path.lineTo(right);
+
+ painter.drawPath(path);
+ }
+
+ }
+ painter.restore();
+}
+
+//////////////////////////////////////////////////////////////////////////////
+QPointF CurveWidget::_getSnapSreenPos(const QPointF& mouseScreenPos)
+{
+ int w = width() - MARGIN_X * 2;
+ int h = height() - MARGIN_Y * 2;
+
+ QPointF pos = _screenToDragedCoordinate(mouseScreenPos);
+
+ // snap horizontally
+ if (_snapHorizontal)
+ {
+ int gridXSegmentCount = GRID_INTIAL_SEGMENT_COUNT / _curveScaleLevel.x();
+ if (gridXSegmentCount < 2)
+ gridXSegmentCount = 2;
+ for (int i = 0; i <= gridXSegmentCount; ++i)
+ {
+ if (abs(i * w / gridXSegmentCount - pos.x()) <= SNAP_DISTANCE )
+ {
+ pos.setX(i * w / gridXSegmentCount);
+ break;
+ }
+ }
+ }
+
+ // snap vertically
+ if (_snapVertical)
+ {
+ int gridYSegmentCount = GRID_INTIAL_SEGMENT_COUNT / _curveScaleLevel.y();
+ if (gridYSegmentCount < 2)
+ gridYSegmentCount = 2;
+ for (int i = 0; i <= gridYSegmentCount; ++i)
+ {
+ if (abs(i * h / gridYSegmentCount - pos.y()) <= SNAP_DISTANCE)
+ {
+ pos.setY(i * h / gridYSegmentCount);
+ }
+ }
+ }
+
+ return _dragedCoordinateToScreen(pos);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+QPointF CurveWidget::_dragedCoordinateToScreen(const QPointF& pnt)
+{
+ float x = pnt.x() + MARGIN_X + _curOrinScreenPos.x();
+ float y = height() - MARGIN_Y - pnt.y() - _curOrinScreenPos.y();
+ return QPointF(x, y);
+}
+
+//////////////////////////////////////////////////////////////////////////////
+QPointF CurveWidget::_screenToDragedCoordinate(const QPointF& pnt)
+{
+ float x = pnt.x() - MARGIN_X - _curOrinScreenPos.x();
+ float y = height() - MARGIN_Y - pnt.y() - _curOrinScreenPos.y();
+ return QPointF(x, y);
+}
+
+} // namespace CurveEditor
+} // namespace nvidia \ No newline at end of file
diff --git a/tools/CurveEditor/source/Internal/Window/CurveWidget.h b/tools/CurveEditor/source/Internal/Window/CurveWidget.h
new file mode 100644
index 0000000..04c38d0
--- /dev/null
+++ b/tools/CurveEditor/source/Internal/Window/CurveWidget.h
@@ -0,0 +1,158 @@
+#ifndef CurveWidget_h__
+#define CurveWidget_h__
+
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QFrame>
+#include <QtWidgets/QLabel>
+#include <QtWidgets/QMenu>
+#include <QtWidgets/QAction>
+#include <vector>
+#include "Curve.h"
+
+namespace nvidia {
+namespace CurveEditor {
+
+class CurveAttributeBase;
+class CurveAttribute;
+class CurveWidget;
+
+class CurveEntity
+{
+ friend class CurveWidget;
+ friend class CurveEditorMainWindow;
+public:
+ CurveEntity(CurveWidget* holder, CurveAttribute* attribute, const QColor& color);
+
+ void setLocation(float location);
+ void setValue(float value);
+
+ void addControlPointsBeforeSelected();
+ void addControlPointsAfterSelected();
+ void removeSelectedControlPoints();
+ void setTangentType(InterpolateMode mode);
+ void setSmoothTangent();
+ void setEaseInTangent();
+ void setEaseOutTangent();
+
+ int getControlPointCount();
+ int getPickedControlPointIndex() { return _pickedPoint; }
+ std::vector<int>& getPickedControlPointIndexes() { return _pickedPoints; }
+
+ QRectF getBoundingBox();
+
+ void mousePressEvent(QMouseEvent* e, bool& pickedPoint);
+ void mouseReleaseEvent(QMouseEvent* e);
+ void mouseMoveEvent(QMouseEvent* e);
+
+ void draw(QPainter &painter);
+
+private:
+ void _drawCurve(QPainter &painter);
+ void _makePoints(std::vector<QPointF>& points);
+ void _drawPoints(const std::vector<QPointF>& points, QPainter &painter, const std::vector<int>& pickedPoints);
+ void _addCtrlPntByClick(const QPointF& mouseScreenPos);
+ bool _canRemoveCtrlPntByRightClick(const QPointF& mouseScreenPos);
+ void _removeCtrlPntByRightClick();
+
+ CurveWidget* _holder;
+ CurveAttribute* _attribute;
+ Curve* _curve;
+ QColor _color;
+ int _pickedPoint;
+ std::vector<int> _pickedPoints;
+ QPointF _lastMousePosScreen;
+ int _ctrlPntToRemove;
+};
+
+class CurveWidget : public QFrame
+{
+ Q_OBJECT
+
+ friend class CurveEntity;
+
+public:
+ explicit CurveWidget(QWidget* parent);
+
+ void setLocation(float location);
+ void setValue(float value);
+
+ void setCurveAttributes(std::vector<CurveAttributeBase*> attributes);
+ void reset();
+
+ void addControlPointsBeforeSelected();
+ void addControlPointsAfterSelected();
+ void removeSelectedControlPoints();
+ void setTangentType(InterpolateMode mode);
+ void setSmoothTangent();
+ void setEaseInTangent();
+ void setEaseOutTangent();
+
+ void setSnapAll() { _snapHorizontal = true; _snapVertical = true; }
+ void setSnapHorizontal() { _snapHorizontal = true; _snapVertical = false; }
+ void setSnapVertical() { _snapHorizontal = false; _snapVertical = true; }
+
+ void increaseCurveScaleHorizontally();
+ void decreaseCurveScaleHorizontally();
+ void increaseCurveScaleVertically();
+ void decreaseCurveScaleVertically();
+ void frameCurveScaleHorizontally();
+ void frameCurveScaleVertically();
+ void frameCurveScale();
+
+ void setAddCtrlPntByClick(bool value) { _canAddCtrlPntByClick = value; }
+ void setRemoveCtrlPntByClick(bool value) { _canRemoveCtrlPntByClick = value; }
+
+signals:
+ void PickedControlPointValueChanged(QPointF& value);
+ void PickedControlPointChanged(const std::vector<CurveEntity*> pickedCurves);
+ void CurveAttributeChanged(nvidia::CurveEditor::CurveAttribute* attribute);
+
+private slots:
+ void onShowContextMenu(const QPoint& pos);
+ void onRemoveControlPoint();
+
+private:
+ // QWidget events
+ virtual void paintEvent(QPaintEvent * e);
+ virtual void resizeEvent(QResizeEvent* e);
+
+ virtual void mousePressEvent(QMouseEvent* e);
+ virtual void mouseReleaseEvent(QMouseEvent* e);
+ virtual void mouseMoveEvent(QMouseEvent* e);
+ virtual void wheelEvent(QWheelEvent *e);
+ virtual void keyPressEvent(QKeyEvent *e);
+
+ void _updateCurveFitWindowPara();
+ QPointF _valueToScreen(const QPointF& pnt);
+ QPointF _screenToValue(const QPointF& pnt);
+ void _drawAxis(QPainter &painter);
+ void _drawGrid(QPainter &painter);
+ QPointF _getSnapSreenPos(const QPointF& mouseScreenPos);
+ QPointF _dragedCoordinateToScreen(const QPointF& pnt);
+ QPointF _screenToDragedCoordinate(const QPointF& pnt);
+
+private:
+ QWidget* _parent;
+ bool _moveCrossOtherCtrlPnt;// whether can move control point across other control points
+ bool _moveCtrlPnt;
+ bool _pan;
+ bool _snapHorizontal;
+ bool _snapVertical;
+ bool _canAddCtrlPntByClick;
+ bool _canRemoveCtrlPntByClick;
+ std::vector<CurveEntity> _curves;
+ QPointF _curveFitWindowScale;
+ QPointF _curveFitWindowOffset;
+ QPointF _curveScaleLevel;
+ QPointF _mousePressScreenPos;
+ QPointF _lastOrinScreenPos;
+ QPointF _curOrinScreenPos;
+
+ QMenu* _contextMenu;
+ QAction* _removeCtrlPntAction;
+};
+
+} // namespace CurveEditor
+} // namespace nvidia
+
+#endif // CurveWidget_h__