|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/tonecurvefield.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/fxhistogramrender.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/intpairfield.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "toonzqt/checkbox.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include <qpainter></qpainter>
|
|
Toshihiro Shimizu |
890ddd |
#include <qpainterpath></qpainterpath>
|
|
Toshihiro Shimizu |
890ddd |
#include <qstackedwidget></qstackedwidget>
|
|
Toshihiro Shimizu |
890ddd |
#include <qmouseevent></qmouseevent>
|
|
Toshihiro Shimizu |
890ddd |
#include <qapplication></qapplication>
|
|
Toshihiro Shimizu |
890ddd |
#include <qhboxlayout></qhboxlayout>
|
|
Toshihiro Shimizu |
890ddd |
#include <qcombobox></qcombobox>
|
|
Toshihiro Shimizu |
890ddd |
#include <qlabel></qlabel>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
using namespace DVGui;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
namespace
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double getPercentAtPoint(QPointF point, QPainterPath path)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 1; i < 100; i++) {
|
|
Toshihiro Shimizu |
890ddd |
double p = double(i) * 0.01;
|
|
Toshihiro Shimizu |
890ddd |
QPointF pathPoint = path.pointAtPercent(p);
|
|
Toshihiro Shimizu |
890ddd |
if (abs(pathPoint.x() - point.x()) < 3 && abs(pathPoint.y() - point.y()) < 3)
|
|
Toshihiro Shimizu |
890ddd |
return p;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QList<qpointf> getIntersectedPoint(QRectF rect, QPainterPath path)</qpointf>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int y0 = rect.top();
|
|
Toshihiro Shimizu |
890ddd |
int y1 = rect.bottom();
|
|
Toshihiro Shimizu |
890ddd |
QList<qpointf> points;</qpointf>
|
|
Toshihiro Shimizu |
890ddd |
double g = 1.0 / 256.0;
|
|
Toshihiro Shimizu |
890ddd |
QPointF prec = path.pointAtPercent(0);
|
|
Toshihiro Shimizu |
890ddd |
QPointF point = path.pointAtPercent(g);
|
|
Toshihiro Shimizu |
890ddd |
int j = 0;
|
|
Toshihiro Shimizu |
890ddd |
for (j = 2; j < 256; j++) {
|
|
Toshihiro Shimizu |
890ddd |
QPointF next = path.pointAtPercent(double(j) * g);
|
|
Toshihiro Shimizu |
890ddd |
if (prec.y() >= y0 && prec.y() <= y1) {
|
|
Toshihiro Shimizu |
890ddd |
if (point.y() < y0)
|
|
Toshihiro Shimizu |
890ddd |
points.push_back(QPointF(prec.x(), y0));
|
|
Toshihiro Shimizu |
890ddd |
else if (point.y() > y1)
|
|
Toshihiro Shimizu |
890ddd |
points.push_back(QPointF(prec.x(), y1));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (next.y() >= y0 && next.y() <= y1) {
|
|
Toshihiro Shimizu |
890ddd |
if (point.y() < y0)
|
|
Toshihiro Shimizu |
890ddd |
points.push_back(QPointF(next.x(), y0));
|
|
Toshihiro Shimizu |
890ddd |
else if (point.y() > y1)
|
|
Toshihiro Shimizu |
890ddd |
points.push_back(QPointF(next.x(), y1));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
prec = point;
|
|
Toshihiro Shimizu |
890ddd |
point = next;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return points;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double qtNorm2(const QPointF &p)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return p.x() * p.x() + p.y() * p.y();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double qtNorm(const QPointF &p)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return sqrt(qtNorm2(p));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QPointF qtNormalize(const QPointF &p)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double n = qtNorm(p);
|
|
Toshihiro Shimizu |
890ddd |
assert(n != 0.0);
|
|
Toshihiro Shimizu |
890ddd |
return (1.0 / n) * p;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double qtDistance2(const QPointF &p1, const QPointF &p2)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return qtNorm2(p2 - p1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
double qtDistance(const QPointF &p1, const QPointF &p2)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return qtNorm(p2 - p1);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QPointF getNewFirstHandlePoint(const QPointF &p, const QPointF &nextP, const QPointF &oldHandlePoint)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
bool canMove = (nextP.x() - p.x() > 16);
|
|
Toshihiro Shimizu |
890ddd |
int yDistance = nextP.y() - p.y();
|
|
Toshihiro Shimizu |
890ddd |
double sign = (yDistance != 0) ? yDistance / abs(yDistance) : 1;
|
|
Toshihiro Shimizu |
890ddd |
double t = qtDistance(p, oldHandlePoint);
|
|
Toshihiro Shimizu |
890ddd |
if (!canMove) {
|
|
Toshihiro Shimizu |
890ddd |
QPointF normalizedP = (yDistance != 0) ? qtNormalize(nextP - p) : QPoint(1, 1);
|
|
Toshihiro Shimizu |
890ddd |
return QPointF(p + QPointF(t * normalizedP));
|
|
Toshihiro Shimizu |
890ddd |
} else if (abs(oldHandlePoint.x() - p.x()) < 16)
|
|
Toshihiro Shimizu |
890ddd |
return QPointF(p.x() + 16, p.y() + sign * sqrt(t * t - 16 * 16));
|
|
Toshihiro Shimizu |
890ddd |
return oldHandlePoint;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QPointF getNewSecondHandlePoint(const QPointF &p, const QPointF &nextP, const QPointF &oldHandlePoint)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
bool canMove = (nextP.x() - p.x() > 16);
|
|
Toshihiro Shimizu |
890ddd |
int yDistance = p.y() - nextP.y();
|
|
Toshihiro Shimizu |
890ddd |
double sign = (yDistance != 0) ? yDistance / abs(yDistance) : 1;
|
|
Toshihiro Shimizu |
890ddd |
double s = qtDistance(oldHandlePoint, nextP);
|
|
Toshihiro Shimizu |
890ddd |
if (!canMove) {
|
|
Toshihiro Shimizu |
890ddd |
QPointF normalizedP = (yDistance != 0) ? qtNormalize(nextP - p) : QPoint(1, 1);
|
|
Toshihiro Shimizu |
890ddd |
return QPointF(nextP - QPointF(s * normalizedP));
|
|
Toshihiro Shimizu |
890ddd |
} else if (abs(nextP.x() - oldHandlePoint.x()) < 16)
|
|
Toshihiro Shimizu |
890ddd |
return QPointF(nextP.x() - 16, nextP.y() + sign * sqrt(s * s - 16 * 16));
|
|
Toshihiro Shimizu |
890ddd |
return oldHandlePoint;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
} //anonymous namespace
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
// ChennelCurveEditor
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ChennelCurveEditor::ChennelCurveEditor(QWidget *parent, HistogramView *histogramView)
|
|
Toshihiro Shimizu |
890ddd |
: QWidget(parent), m_histogramView(histogramView), m_currentControlPointIndex(-1), m_mouseButton(Qt::NoButton), m_curveHeight(256), m_LeftRightMargin(42), m_TopMargin(9), m_BottomMargin(48), m_isLinear(false)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
setFixedSize(m_curveHeight + 2 * m_LeftRightMargin + 2,
|
|
Toshihiro Shimizu |
890ddd |
m_curveHeight + m_TopMargin + m_BottomMargin);
|
|
Toshihiro Shimizu |
890ddd |
setAttribute(Qt::WA_KeyCompression);
|
|
Toshihiro Shimizu |
890ddd |
setFocusPolicy(Qt::StrongFocus);
|
|
Toshihiro Shimizu |
890ddd |
setMouseTracking(true);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_histogramView->setDrawnWidget(this);
|
|
Toshihiro Shimizu |
890ddd |
m_histogramView->setGraphHeight(m_curveHeight);
|
|
Toshihiro Shimizu |
890ddd |
m_histogramView->setGraphAlphaMask(120);
|
|
Toshihiro Shimizu |
890ddd |
m_verticalChannelBar = new ChannelBar(0, m_histogramView->getChannelBarColor(), false);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::setPoints(QList<tpointd> points)</tpointd>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!m_points.isEmpty())
|
|
Toshihiro Shimizu |
890ddd |
m_points.clear();
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < points.size(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
QPointF p = strokeToViewPoint(points.at(i));
|
|
Toshihiro Shimizu |
890ddd |
m_points.push_back(p);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*--ポイント位置に合わせてスライダも更新する--*/
|
|
Toshihiro Shimizu |
890ddd |
int firstIndex = 3;
|
|
Toshihiro Shimizu |
890ddd |
int lastIndex = m_points.size() - 4;
|
|
Toshihiro Shimizu |
890ddd |
emit firstLastXPostionChanged(viewToStrokePoint(m_points.at(firstIndex)).x,
|
|
Toshihiro Shimizu |
890ddd |
viewToStrokePoint(m_points.at(lastIndex)).x);
|
|
Toshihiro Shimizu |
890ddd |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QList<tpointd> ChennelCurveEditor::getPoints()</tpointd>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QList<tpointd> points;</tpointd>
|
|
Toshihiro Shimizu |
890ddd |
if (m_points.isEmpty())
|
|
Toshihiro Shimizu |
890ddd |
return points;
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < m_points.size(); i++)
|
|
Toshihiro Shimizu |
890ddd |
points.push_back(viewToStrokePoint(m_points.at(i)));
|
|
Toshihiro Shimizu |
890ddd |
return points;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::setFirstLastXPosition(std::pair<int, int=""> values, bool isDragging)</int,>
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (!isDragging) {
|
|
Toshihiro Shimizu |
890ddd |
emit controlPointChanged(false);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QPointF newX0 = strokeToViewPoint(TPointD(values.first, 0));
|
|
Toshihiro Shimizu |
890ddd |
QPointF newX1 = strokeToViewPoint(TPointD(values.second, 0));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int indexX0 = 3;
|
|
Toshihiro Shimizu |
890ddd |
int indexX1 = m_points.size() - 4;
|
|
Toshihiro Shimizu |
890ddd |
QPointF x0 = m_points.at(indexX0);
|
|
Toshihiro Shimizu |
890ddd |
QPointF x1 = m_points.at(indexX1);
|
|
Toshihiro Shimizu |
890ddd |
if (x0.x() != newX0.x()) {
|
|
Toshihiro Shimizu |
890ddd |
QPointF delta(newX0.x() - x0.x(), 0);
|
|
Toshihiro Shimizu |
890ddd |
moveCentralControlPoint(indexX0, delta);
|
|
Toshihiro Shimizu |
890ddd |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (x1.x() != newX1.x()) {
|
|
Toshihiro Shimizu |
890ddd |
QPointF delta(newX1.x() - x1.x(), 0);
|
|
Toshihiro Shimizu |
890ddd |
moveCentralControlPoint(indexX1, delta);
|
|
Toshihiro Shimizu |
890ddd |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
m_currentControlPointIndex = -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::setLinear(bool isLinear)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_isLinear == isLinear)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
m_isLinear = isLinear;
|
|
Toshihiro Shimizu |
890ddd |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QPointF ChennelCurveEditor::checkPoint(const QPointF p)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QPointF checkedP = p;
|
|
Toshihiro Shimizu |
890ddd |
int y0 = m_TopMargin + 1;
|
|
Toshihiro Shimizu |
890ddd |
int y1 = m_curveHeight + m_TopMargin;
|
|
Toshihiro Shimizu |
890ddd |
if (p.y() < y0)
|
|
Toshihiro Shimizu |
890ddd |
checkedP = QPointF(checkedP.x(), y0);
|
|
Toshihiro Shimizu |
890ddd |
if (p.y() > y1)
|
|
Toshihiro Shimizu |
890ddd |
checkedP = QPointF(checkedP.x(), y1);
|
|
Toshihiro Shimizu |
890ddd |
int x0 = m_LeftRightMargin + 1;
|
|
Toshihiro Shimizu |
890ddd |
int x1 = m_curveHeight + m_LeftRightMargin;
|
|
Toshihiro Shimizu |
890ddd |
if (p.x() < x0)
|
|
Toshihiro Shimizu |
890ddd |
checkedP = QPointF(x0, checkedP.y());
|
|
Toshihiro Shimizu |
890ddd |
if (p.x() > x1)
|
|
Toshihiro Shimizu |
890ddd |
checkedP = QPointF(x1, checkedP.y());
|
|
Toshihiro Shimizu |
890ddd |
return checkedP;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QPointF ChennelCurveEditor::strokeToViewPoint(const TPointD p)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double x = p.x + m_LeftRightMargin + 1;
|
|
Toshihiro Shimizu |
890ddd |
double y = height() - m_BottomMargin - p.y;
|
|
Toshihiro Shimizu |
890ddd |
return QPointF(x, y);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
TPointD ChennelCurveEditor::viewToStrokePoint(const QPointF &p)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
double x = p.x() - m_LeftRightMargin - 1;
|
|
Toshihiro Shimizu |
890ddd |
double y = m_curveHeight - (p.y() - m_TopMargin);
|
|
Toshihiro Shimizu |
890ddd |
return TThickPoint(x, y);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int ChennelCurveEditor::getClosestPointIndex(const QPointF &pos, double &minDistance2) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int closestPointIndex = -1;
|
|
Toshihiro Shimizu |
890ddd |
minDistance2 = 0;
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < (int)m_points.size(); i++) {
|
|
Toshihiro Shimizu |
890ddd |
double distance2 = qtDistance2(pos, m_points.at(i));
|
|
Toshihiro Shimizu |
890ddd |
if (closestPointIndex < 0 || distance2 < minDistance2) {
|
|
Toshihiro Shimizu |
890ddd |
minDistance2 = distance2;
|
|
Toshihiro Shimizu |
890ddd |
closestPointIndex = i;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return closestPointIndex;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::movePoint(int index, const QPointF delta)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QPointF p = m_points.at(index);
|
|
Toshihiro Shimizu |
890ddd |
p += delta;
|
|
Toshihiro Shimizu |
890ddd |
setPoint(index, p);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int firstIndex = 3;
|
|
Toshihiro Shimizu |
890ddd |
int lastIndex = m_points.size() - 4;
|
|
Toshihiro Shimizu |
890ddd |
if (index == firstIndex)
|
|
Toshihiro Shimizu |
890ddd |
emit firstLastXPostionChanged(viewToStrokePoint(p).x, viewToStrokePoint(m_points.at(lastIndex)).x);
|
|
Toshihiro Shimizu |
890ddd |
if (index == lastIndex)
|
|
Toshihiro Shimizu |
890ddd |
emit firstLastXPostionChanged(viewToStrokePoint(m_points.at(firstIndex)).x, viewToStrokePoint(p).x);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::setPoint(int index, const QPointF p)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_points.removeAt(index);
|
|
Toshihiro Shimizu |
890ddd |
m_points.insert(index, p);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int firstIndex = 3;
|
|
Toshihiro Shimizu |
890ddd |
int lastIndex = m_points.size() - 4;
|
|
Toshihiro Shimizu |
890ddd |
if (index == firstIndex)
|
|
Toshihiro Shimizu |
890ddd |
emit firstLastXPostionChanged(viewToStrokePoint(p).x, viewToStrokePoint(m_points.at(lastIndex)).x);
|
|
Toshihiro Shimizu |
890ddd |
if (index == lastIndex)
|
|
Toshihiro Shimizu |
890ddd |
emit firstLastXPostionChanged(viewToStrokePoint(m_points.at(firstIndex)).x, viewToStrokePoint(p).x);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::moveCurrentControlPoint(const QPointF delta)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
assert(m_currentControlPointIndex != -1);
|
|
Toshihiro Shimizu |
890ddd |
int pointCount = m_points.size();
|
|
Toshihiro Shimizu |
890ddd |
/*- セグメントを動かした場合 -*/
|
|
Toshihiro Shimizu |
890ddd |
if (isCentralControlPoint(m_currentControlPointIndex))
|
|
Toshihiro Shimizu |
890ddd |
moveCentralControlPoint(m_currentControlPointIndex, delta);
|
|
Toshihiro Shimizu |
890ddd |
/*- 左のハンドルを動かした場合 -*/
|
|
Toshihiro Shimizu |
890ddd |
else if (isLeftControlPoint(m_currentControlPointIndex)) {
|
|
Toshihiro Shimizu |
890ddd |
QPointF p0 = m_points.at(m_currentControlPointIndex) + QPointF(0, delta.y());
|
|
Toshihiro Shimizu |
890ddd |
setPoint(m_currentControlPointIndex, p0);
|
|
Toshihiro Shimizu |
890ddd |
if (m_currentControlPointIndex < pointCount - 5) {
|
|
Toshihiro Shimizu |
890ddd |
QPointF p2 = m_points.at(m_currentControlPointIndex + 2) - QPointF(0, delta.y());
|
|
Toshihiro Shimizu |
890ddd |
setPoint(m_currentControlPointIndex + 2, p2);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
emit controlPointChanged(true);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*- 右のハンドルを動かした場合 -*/
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
assert(isRightControlPoint(m_currentControlPointIndex));
|
|
Toshihiro Shimizu |
890ddd |
QPointF p0 = m_points.at(m_currentControlPointIndex) + QPointF(0, delta.y());
|
|
Toshihiro Shimizu |
890ddd |
setPoint(m_currentControlPointIndex, p0);
|
|
Toshihiro Shimizu |
890ddd |
if (m_currentControlPointIndex > 4) {
|
|
Toshihiro Shimizu |
890ddd |
QPointF p2 = m_points.at(m_currentControlPointIndex - 2) - QPointF(0, delta.y());
|
|
Toshihiro Shimizu |
890ddd |
setPoint(m_currentControlPointIndex - 2, p2);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
emit controlPointChanged(true);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::moveCentralControlPoint(int index, const QPointF delta)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int pointCount = m_points.size();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
assert(index < pointCount - 3 && index > 2);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QPointF p = m_points.at(index);
|
|
Toshihiro Shimizu |
890ddd |
QPointF d = delta;
|
|
Toshihiro Shimizu |
890ddd |
//Trovo il valore di delta im modo tale che il punto di controllo non sia trascinato fuori dal range consentito
|
|
Toshihiro Shimizu |
890ddd |
int newX = p.x() + delta.x();
|
|
Toshihiro Shimizu |
890ddd |
int newY = p.y() + delta.y();
|
|
Toshihiro Shimizu |
890ddd |
QPointF newPoint = checkPoint(QPoint(newX, newY));
|
|
Toshihiro Shimizu |
890ddd |
d = newPoint - p;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QPointF nextP = m_points.at(index + 3);
|
|
Toshihiro Shimizu |
890ddd |
QPointF precP = m_points.at(index - 3);
|
|
Toshihiro Shimizu |
890ddd |
double nextDistance = nextP.x() - (p.x() + d.x());
|
|
Toshihiro Shimizu |
890ddd |
double precDistance = (p.x() + d.x()) - precP.x();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Caso particolare: Punto di controllo corrente == primo visibile,
|
|
Toshihiro Shimizu |
890ddd |
// Punto di controllo successivo == l'ultimo visibile
|
|
Toshihiro Shimizu |
890ddd |
if (index == 3 && index + 3 == pointCount - 4) {
|
|
Toshihiro Shimizu |
890ddd |
setPoint(index + 1, getNewFirstHandlePoint(p, nextP, m_points.at(index + 1)));
|
|
Toshihiro Shimizu |
890ddd |
setPoint(index + 2, getNewSecondHandlePoint(p, nextP, m_points.at(index + 2)));
|
|
Toshihiro Shimizu |
890ddd |
if (nextDistance < 0)
|
|
Toshihiro Shimizu |
890ddd |
d = QPointF(nextP.x() - p.x(), d.y());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//Caso particolare: Punto di controllo corrente == ultimo visibile,
|
|
Toshihiro Shimizu |
890ddd |
// Punto di controllo precedente == primo visibile
|
|
Toshihiro Shimizu |
890ddd |
else if (index - 3 == 3 && index == pointCount - 4) {
|
|
Toshihiro Shimizu |
890ddd |
setPoint(index - 2, getNewFirstHandlePoint(precP, p, m_points.at(index - 2)));
|
|
Toshihiro Shimizu |
890ddd |
setPoint(index - 1, getNewSecondHandlePoint(precP, p, m_points.at(index - 1)));
|
|
Toshihiro Shimizu |
890ddd |
if (precDistance < 0)
|
|
Toshihiro Shimizu |
890ddd |
d = QPointF(precP.x() - p.x(), d.y());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//Altrimenti calcolo il nuovo delta
|
|
Toshihiro Shimizu |
890ddd |
else if (nextDistance < 16)
|
|
Toshihiro Shimizu |
890ddd |
d = QPointF(nextP.x() - p.x() - 16, d.y());
|
|
Toshihiro Shimizu |
890ddd |
else if (precDistance < 16)
|
|
Toshihiro Shimizu |
890ddd |
d = QPointF(precP.x() - p.x() + 16, d.y());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Punto di controllo speciale: il primo visualizzato.
|
|
Toshihiro Shimizu |
890ddd |
if (index == 3) {
|
|
Toshihiro Shimizu |
890ddd |
QPointF dY = QPointF(0, d.y());
|
|
Toshihiro Shimizu |
890ddd |
movePoint(index - 1, dY);
|
|
Toshihiro Shimizu |
890ddd |
movePoint(index - 2, dY);
|
|
Toshihiro Shimizu |
890ddd |
movePoint(index - 3, dY);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//Punto di controllo speciale: l'ultimo visualizzato.
|
|
Toshihiro Shimizu |
890ddd |
if (index == pointCount - 4) {
|
|
Toshihiro Shimizu |
890ddd |
QPointF dY = QPointF(0, d.y());
|
|
Toshihiro Shimizu |
890ddd |
movePoint(index + 1, dY);
|
|
Toshihiro Shimizu |
890ddd |
movePoint(index + 2, dY);
|
|
Toshihiro Shimizu |
890ddd |
movePoint(index + 3, dY);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (index > 3)
|
|
Toshihiro Shimizu |
890ddd |
movePoint(index - 1, d);
|
|
Toshihiro Shimizu |
890ddd |
if (index < pointCount - 4)
|
|
Toshihiro Shimizu |
890ddd |
movePoint(index + 1, d);
|
|
Toshihiro Shimizu |
890ddd |
movePoint(index, d);
|
|
Toshihiro Shimizu |
890ddd |
emit controlPointChanged(true);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/* Se due punti di controllo sono troppo vicini uno dei due viene eliminato.
|
|
Toshihiro Shimizu |
890ddd |
Ritorna vero se un punto viene eliminato.
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
Prima di richiamare il metodo nel move andava fatto questo controllo!!!
|
|
Toshihiro Shimizu |
890ddd |
//Se il punto di controllo successivo, o precente, e' l'utlimo, o il primo, blocco il
|
|
Toshihiro Shimizu |
890ddd |
// movimento altrimenti elimino il punto di controllo successivo e richiamo il move.
|
|
Toshihiro Shimizu |
890ddd |
int nextPX = m_points.at(index+3).x();
|
|
Toshihiro Shimizu |
890ddd |
if(nextPX>m_margin && nextPX<=w && newX>nextPX)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if(index+3 == pointCount-4) d = QPointF(0, d.y());
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
moveCentralControlPoint(index, d);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
int precPX = m_points.at(index-3).x();
|
|
Toshihiro Shimizu |
890ddd |
if(precPX>=m_margin && precPX<=w && newX
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if(index-3 == 3) d = QPointF(0, d.y());
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
moveCentralControlPoint(index, d);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool ChennelCurveEditor::eraseControlPointWhileMove(int index, const QPointF delta)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int pointCount = m_points.size();
|
|
Toshihiro Shimizu |
890ddd |
QPointF p = m_points.at(index);
|
|
Toshihiro Shimizu |
890ddd |
QPointF nextP = m_points.at(index+3);
|
|
Toshihiro Shimizu |
890ddd |
QPointF precP = m_points.at(index-3);
|
|
Toshihiro Shimizu |
890ddd |
double nextDistance = abs((p.x()+delta.x())-nextP.x());
|
|
Toshihiro Shimizu |
890ddd |
double precDistance = abs((p.x()+delta.x())-precP.x());
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if(nextDistance>16 && precDistance>16) return false;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Se vado troppo vicino al punto di controllo precedente, o successivo, lo elimino.
|
|
Toshihiro Shimizu |
890ddd |
if(nextDistance<=16)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Caso particolare: il successivo e' l'ultimo visibile; non posso eliminare l'ultimo punto di controllo visibile.
|
|
Toshihiro Shimizu |
890ddd |
if(index+3 == pointCount-4)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Se il punto di controllo in index e' il primo visibile sto gestendo il
|
|
Toshihiro Shimizu |
890ddd |
// primo e l'ultimo punto, entrambi non possono essere eliminati.
|
|
Toshihiro Shimizu |
890ddd |
if(index == 3)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
setPoint(index+1,nextP);
|
|
Toshihiro Shimizu |
890ddd |
setPoint(index+2,p+delta);
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
else //Altrimenti elimino il penultimo.
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
removeControlPoint(index);
|
|
Toshihiro Shimizu |
890ddd |
m_currentControlPointIndex += 3;
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
removeControlPoint(index+3);
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if(precDistance<=16)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Caso particolare: il precedente e' il primo visibile; non posso eliminare il primo punto di controllo visibile.
|
|
Toshihiro Shimizu |
890ddd |
if(index-3 == 3)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Se il punto di controllo in index e' l'ultimo visibile sto gestendo il
|
|
Toshihiro Shimizu |
890ddd |
// primo e l'ultimo punto, entrambi non possono essere eliminati.
|
|
Toshihiro Shimizu |
890ddd |
if(index == pointCount-4)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
setPoint(index-1,precP);
|
|
Toshihiro Shimizu |
890ddd |
setPoint(index-2,p+delta);
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
else //Altrimenti elimino il secondo.
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
removeControlPoint(index);
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
removeControlPoint(index-3);
|
|
Toshihiro Shimizu |
890ddd |
m_currentControlPointIndex += 3;
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::addControlPoint(double percent)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QPainterPath path = getPainterPath();
|
|
Toshihiro Shimizu |
890ddd |
QPointF p = path.pointAtPercent(percent);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Cerco il punto di controllo precedente
|
|
Toshihiro Shimizu |
890ddd |
int pointCount = m_points.size();
|
|
Toshihiro Shimizu |
890ddd |
int beforeControlPointIndex;
|
|
Toshihiro Shimizu |
890ddd |
for (beforeControlPointIndex = pointCount - 1; beforeControlPointIndex >= 0; beforeControlPointIndex--) {
|
|
Toshihiro Shimizu |
890ddd |
QPointF point = m_points.at(beforeControlPointIndex);
|
|
Toshihiro Shimizu |
890ddd |
if (isCentralControlPoint(beforeControlPointIndex) && point.x() < p.x())
|
|
Toshihiro Shimizu |
890ddd |
break;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (beforeControlPointIndex == 0 || beforeControlPointIndex == pointCount - 4)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QPointF p0 = checkPoint(m_points.at(beforeControlPointIndex));
|
|
Toshihiro Shimizu |
890ddd |
//Se sono troppo vicino al punto di controllo precedente ritorno
|
|
Toshihiro Shimizu |
890ddd |
if (abs(p.x() - p0.x()) <= 16)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
double beforeControlPointPercent = getPercentAtPoint(p0, path);
|
|
Toshihiro Shimizu |
890ddd |
QPointF p1 = checkPoint(m_points.at(beforeControlPointIndex + 1));
|
|
Toshihiro Shimizu |
890ddd |
QPointF p2 = checkPoint(m_points.at(beforeControlPointIndex + 2));
|
|
Toshihiro Shimizu |
890ddd |
QPointF p3 = checkPoint(m_points.at(beforeControlPointIndex + 3));
|
|
Toshihiro Shimizu |
890ddd |
//Se sono troppo vicino al punto di controllo successivo ritorno
|
|
Toshihiro Shimizu |
890ddd |
if (abs(p3.x() - p.x()) <= 16)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
double nextControlPointPercent = getPercentAtPoint(p3, path);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Calcolo la velocita' e quindi il coiffciente angolare.
|
|
Toshihiro Shimizu |
890ddd |
double t = percent * 100 / (nextControlPointPercent - beforeControlPointPercent);
|
|
Toshihiro Shimizu |
890ddd |
double s = t - 1;
|
|
Toshihiro Shimizu |
890ddd |
QPointF speed = 3.0 * ((p1 - p0) * s * s + 2 * (p2 - p0) * s * t + (p3 - p2) * t * t);
|
|
Toshihiro Shimizu |
890ddd |
double m = speed.y() / speed.x();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int newControlPointIndex = beforeControlPointIndex + 3;
|
|
Toshihiro Shimizu |
890ddd |
m_points.insert(newControlPointIndex - 1, QPointF(p.x() - 16, p.y() - 16 * m));
|
|
Toshihiro Shimizu |
890ddd |
m_points.insert(newControlPointIndex, p);
|
|
Toshihiro Shimizu |
890ddd |
m_points.insert(newControlPointIndex + 1, QPointF(p.x() + 16, p.y() + 16 * m));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_currentControlPointIndex = newControlPointIndex;
|
|
Toshihiro Shimizu |
890ddd |
emit controlPointAdded(newControlPointIndex);
|
|
Toshihiro Shimizu |
890ddd |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::removeCurrentControlPoint()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
removeControlPoint(m_currentControlPointIndex);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::removeControlPoint(int index)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
//Non posso eliminare il primo punto di controllo visibile quindi lo rimetto in condizione iniziale
|
|
Toshihiro Shimizu |
890ddd |
if (index <= 4) {
|
|
Toshihiro Shimizu |
890ddd |
setPoint(0, strokeToViewPoint(TPointD(-40, 0)));
|
|
Toshihiro Shimizu |
890ddd |
setPoint(1, strokeToViewPoint(TPointD(-20, 0)));
|
|
Toshihiro Shimizu |
890ddd |
setPoint(2, strokeToViewPoint(TPointD(-20, 0)));
|
|
Toshihiro Shimizu |
890ddd |
setPoint(3, strokeToViewPoint(TPointD(0, 0)));
|
|
Toshihiro Shimizu |
890ddd |
setPoint(4, strokeToViewPoint(TPointD(16, 16)));
|
|
Toshihiro Shimizu |
890ddd |
update();
|
|
Toshihiro Shimizu |
890ddd |
emit controlPointChanged(false);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//Non posso eliminare il l'ultimo punto di controllo visibile quindi lo rimetto in condizione iniziale
|
|
Toshihiro Shimizu |
890ddd |
if (index >= m_points.size() - 5) {
|
|
Toshihiro Shimizu |
890ddd |
int i = m_points.size() - 5;
|
|
Toshihiro Shimizu |
890ddd |
setPoint(i, strokeToViewPoint(TPointD(239, 239)));
|
|
Toshihiro Shimizu |
890ddd |
setPoint(i + 1, strokeToViewPoint(TPointD(255, 255)));
|
|
Toshihiro Shimizu |
890ddd |
setPoint(i + 2, strokeToViewPoint(TPointD(275, 255)));
|
|
Toshihiro Shimizu |
890ddd |
setPoint(i + 3, strokeToViewPoint(TPointD(275, 255)));
|
|
Toshihiro Shimizu |
890ddd |
setPoint(i + 4, strokeToViewPoint(TPointD(295, 255)));
|
|
Toshihiro Shimizu |
890ddd |
update();
|
|
Toshihiro Shimizu |
890ddd |
emit controlPointChanged(false);
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int firstIndex = 0;
|
|
Toshihiro Shimizu |
890ddd |
if (isCentralControlPoint(index))
|
|
Toshihiro Shimizu |
890ddd |
firstIndex = index - 1;
|
|
Toshihiro Shimizu |
890ddd |
else if (isLeftControlPoint(index))
|
|
Toshihiro Shimizu |
890ddd |
firstIndex = index;
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
firstIndex = index - 2;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
m_points.removeAt(firstIndex);
|
|
Toshihiro Shimizu |
890ddd |
m_points.removeAt(firstIndex);
|
|
Toshihiro Shimizu |
890ddd |
m_points.removeAt(firstIndex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
emit controlPointRemoved(firstIndex + 1);
|
|
Toshihiro Shimizu |
890ddd |
m_currentControlPointIndex = firstIndex - 2;
|
|
Toshihiro Shimizu |
890ddd |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QPainterPath ChennelCurveEditor::getPainterPath()
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int pointCount = m_points.size();
|
|
Toshihiro Shimizu |
890ddd |
if (pointCount == 0)
|
|
Toshihiro Shimizu |
890ddd |
return QPainterPath();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QPointF p0 = m_points.at(0);
|
|
Toshihiro Shimizu |
890ddd |
QPainterPath path(p0);
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 1; i < pointCount; i++) {
|
|
Toshihiro Shimizu |
890ddd |
QPointF p1 = m_points.at(i);
|
|
Toshihiro Shimizu |
890ddd |
QPointF p2 = m_points.at(++i);
|
|
Toshihiro Shimizu |
890ddd |
QPointF p3 = m_points.at(++i);
|
|
Toshihiro Shimizu |
890ddd |
path.moveTo(p0);
|
|
Toshihiro Shimizu |
890ddd |
if (!m_isLinear)
|
|
Toshihiro Shimizu |
890ddd |
path.cubicTo(p1, p2, p3);
|
|
Toshihiro Shimizu |
890ddd |
else
|
|
Toshihiro Shimizu |
890ddd |
path.lineTo(p3);
|
|
Toshihiro Shimizu |
890ddd |
p0 = p3;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Cerco le eventuali intersezioni con il bordo.
|
|
Toshihiro Shimizu |
890ddd |
QRectF rect(m_LeftRightMargin, m_TopMargin, m_curveHeight, m_curveHeight);
|
|
Toshihiro Shimizu |
890ddd |
QRectF r = path.boundingRect();
|
|
Toshihiro Shimizu |
890ddd |
if (!rect.contains(QRect(rect.left(), r.top(), rect.width(), r.height()))) {
|
|
Toshihiro Shimizu |
890ddd |
QList<qpointf> points = getIntersectedPoint(rect, path);</qpointf>
|
|
Toshihiro Shimizu |
890ddd |
//Se trovo punti di intersezione (per come e' definita la curva devono essere pari)
|
|
Toshihiro Shimizu |
890ddd |
// faccio l'unione del path calcolato e di nuovi path lineari.
|
|
Toshihiro Shimizu |
890ddd |
int j = 0;
|
|
Toshihiro Shimizu |
890ddd |
for (j = 0; j < points.size(); j++) {
|
|
Toshihiro Shimizu |
890ddd |
QPointF p0 = points.at(j);
|
|
Toshihiro Shimizu |
890ddd |
QPointF p1 = points.at(++j);
|
|
Toshihiro Shimizu |
890ddd |
QPainterPath line(p0);
|
|
Toshihiro Shimizu |
890ddd |
line.lineTo(p1);
|
|
Toshihiro Shimizu |
890ddd |
path.addPath(line);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
return path;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::paintEvent(QPaintEvent *e)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QPainter painter(this);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Disegno il reticolato
|
|
Toshihiro Shimizu |
890ddd |
painter.setRenderHint(QPainter::Antialiasing, false);
|
|
Toshihiro Shimizu |
890ddd |
painter.setPen(QColor(250, 250, 250));
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
int d = m_curveHeight * 0.25;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 1; i < 16; i++) {
|
|
Toshihiro Shimizu |
890ddd |
// linee orizzontali
|
|
Toshihiro Shimizu |
890ddd |
int delta = m_TopMargin + 16 * i;
|
|
Toshihiro Shimizu |
890ddd |
int j;
|
|
Toshihiro Shimizu |
890ddd |
for (j = 1; j < 4; j++)
|
|
Toshihiro Shimizu |
890ddd |
painter.drawLine(QPoint((j - 1) * d + m_LeftRightMargin + 1, delta), QPoint(j * d + m_LeftRightMargin - 1, delta));
|
|
Toshihiro Shimizu |
890ddd |
painter.drawLine(QPoint((4 - 1) * d + m_LeftRightMargin + 1, delta), QPoint(4 * d + m_LeftRightMargin, delta));
|
|
Toshihiro Shimizu |
890ddd |
// linee verticali
|
|
Toshihiro Shimizu |
890ddd |
delta = m_LeftRightMargin + 1 + 16 * i;
|
|
Toshihiro Shimizu |
890ddd |
if (i % 4 == 0)
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
for (j = 1; j < 5; j++)
|
|
Toshihiro Shimizu |
890ddd |
painter.drawLine(QPoint(delta, (j - 1) * d + m_TopMargin), QPoint(delta, j * d + m_TopMargin - 1));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Disegno l'histogram.
|
|
Toshihiro Shimizu |
890ddd |
m_histogramView->draw(&painter, QPoint(m_LeftRightMargin - 10, 0));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Disegno la barra verticale a sinistra.
|
|
Toshihiro Shimizu |
890ddd |
m_verticalChannelBar->draw(&painter, QPoint(0, -2)); //-1 == m_topMargin- il margine della barra(=10+1).
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QRectF r = rect().adjusted(m_LeftRightMargin, m_TopMargin, -m_LeftRightMargin, -m_BottomMargin);
|
|
Toshihiro Shimizu |
890ddd |
//Disegno la curva entro i limiti del grafo
|
|
Toshihiro Shimizu |
890ddd |
painter.setClipRect(r, Qt::IntersectClip);
|
|
Toshihiro Shimizu |
890ddd |
QPainterPath path = getPainterPath();
|
|
Toshihiro Shimizu |
890ddd |
if (path.isEmpty())
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
painter.setRenderHint(QPainter::Antialiasing, true);
|
|
Toshihiro Shimizu |
890ddd |
painter.setPen(Qt::black);
|
|
Toshihiro Shimizu |
890ddd |
painter.setBrush(Qt::NoBrush);
|
|
Toshihiro Shimizu |
890ddd |
painter.drawPath(path);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Disegno i punti di controllo (esclusi i primi tre e gli ultimi tre)
|
|
Toshihiro Shimizu |
890ddd |
r = r.adjusted(-5, -5, 5, 5);
|
|
Toshihiro Shimizu |
890ddd |
int n = m_points.size();
|
|
Toshihiro Shimizu |
890ddd |
QPointF p = m_points.at(3);
|
|
Toshihiro Shimizu |
890ddd |
for (i = 3; i < n - 3; i++) {
|
|
Toshihiro Shimizu |
890ddd |
QBrush brush(Qt::white);
|
|
Toshihiro Shimizu |
890ddd |
int rad = 3;
|
|
Toshihiro Shimizu |
890ddd |
QPointF nextP = m_points.at(i + 1);
|
|
Toshihiro Shimizu |
890ddd |
if (isCentralControlPoint(i))
|
|
Toshihiro Shimizu |
890ddd |
rad = 4;
|
|
Toshihiro Shimizu |
890ddd |
else if (m_isLinear) {
|
|
Toshihiro Shimizu |
890ddd |
p = nextP;
|
|
Toshihiro Shimizu |
890ddd |
continue;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
if (m_currentControlPointIndex == i)
|
|
Toshihiro Shimizu |
890ddd |
brush = QBrush(Qt::black);
|
|
Toshihiro Shimizu |
890ddd |
painter.setBrush(brush);
|
|
Toshihiro Shimizu |
890ddd |
painter.setPen(Qt::black);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
if (!m_isLinear) {
|
|
Toshihiro Shimizu |
890ddd |
if (isLeftControlPoint(i))
|
|
Toshihiro Shimizu |
890ddd |
painter.drawLine(p, nextP);
|
|
Toshihiro Shimizu |
890ddd |
else if (isCentralControlPoint(i) && i < n - 4)
|
|
Toshihiro Shimizu |
890ddd |
painter.drawLine(p, nextP);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
QPainterPath circle;
|
|
Toshihiro Shimizu |
890ddd |
QRectF pointRect(p.x() - rad, p.y() - rad, 2 * rad, 2 * rad);
|
|
Toshihiro Shimizu |
890ddd |
if (r.contains(pointRect))
|
|
Toshihiro Shimizu |
890ddd |
#if QT_VERSION >= 0x050000
|
|
Toshihiro Shimizu |
890ddd |
painter.setClipRect(pointRect.adjusted(-1, -1, 1, 1));
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
painter.setClipRect(pointRect.adjusted(-1, -1, 1, 1), Qt::UniteClip);
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
circle.addEllipse(pointRect);
|
|
Toshihiro Shimizu |
890ddd |
painter.fillPath(circle, brush);
|
|
Toshihiro Shimizu |
890ddd |
painter.drawPath(circle);
|
|
Toshihiro Shimizu |
890ddd |
p = nextP;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::mouseMoveEvent(QMouseEvent *e)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_mouseButton == Qt::LeftButton && m_currentControlPointIndex != -1) {
|
|
Toshihiro Shimizu |
890ddd |
QPoint pos = e->pos();
|
|
Toshihiro Shimizu |
890ddd |
QPointF posF = QPointF(pos.x(), pos.y());
|
|
Toshihiro Shimizu |
890ddd |
moveCurrentControlPoint(posF - m_points.at(m_currentControlPointIndex));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::mousePressEvent(QMouseEvent *e)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_mouseButton = e->button();
|
|
Toshihiro Shimizu |
890ddd |
setFocus();
|
|
Toshihiro Shimizu |
890ddd |
if (m_mouseButton == Qt::LeftButton) {
|
|
Toshihiro Shimizu |
890ddd |
QPoint pos = e->pos();
|
|
Toshihiro Shimizu |
890ddd |
QPointF posF = QPointF(pos.x(), pos.y());
|
|
Toshihiro Shimizu |
890ddd |
double minDistance;
|
|
Toshihiro Shimizu |
890ddd |
int controlPointIndex = getClosestPointIndex(posF, minDistance);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//Se la distanza e' piccola seleziono il control point corrente
|
|
Toshihiro Shimizu |
890ddd |
if (minDistance < 20)
|
|
Toshihiro Shimizu |
890ddd |
m_currentControlPointIndex = controlPointIndex;
|
|
Toshihiro Shimizu |
890ddd |
else {
|
|
Toshihiro Shimizu |
890ddd |
m_currentControlPointIndex = -1;
|
|
Toshihiro Shimizu |
890ddd |
//Se sono sufficentemente lontano da un punto di controllo, ma abbastanza vicino alla curva
|
|
Toshihiro Shimizu |
890ddd |
// aggiungo un punto di controllo
|
|
Toshihiro Shimizu |
890ddd |
double percent = getPercentAtPoint(posF, getPainterPath());
|
|
Toshihiro Shimizu |
890ddd |
if (percent != 0 && minDistance > 20)
|
|
Toshihiro Shimizu |
890ddd |
addControlPoint(percent);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::mouseReleaseEvent(QMouseEvent *e)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
/*-- マウスドラッグ中はプレビューを更新しない。ここで初めて更新 --*/
|
|
Toshihiro Shimizu |
890ddd |
if (m_mouseButton == Qt::LeftButton &&
|
|
Toshihiro Shimizu |
890ddd |
m_currentControlPointIndex != -1 &&
|
|
Toshihiro Shimizu |
890ddd |
e->button() == Qt::LeftButton)
|
|
Toshihiro Shimizu |
890ddd |
emit controlPointChanged(false);
|
|
Toshihiro Shimizu |
890ddd |
m_mouseButton = Qt::NoButton;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::keyPressEvent(QKeyEvent *e)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (e->key() == Qt::Key_Delete)
|
|
Toshihiro Shimizu |
890ddd |
removeCurrentControlPoint();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::enterEvent(QEvent *)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_mouseButton = Qt::NoButton;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::leaveEvent(QEvent *)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_mouseButton = Qt::NoButton;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
bool ChennelCurveEditor::eventFilter(QObject *object, QEvent *event)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (event->type() == QEvent::Shortcut ||
|
|
Toshihiro Shimizu |
890ddd |
event->type() == QEvent::ShortcutOverride) {
|
|
Toshihiro Shimizu |
890ddd |
if (!object->inherits("FxSettings")) {
|
|
Toshihiro Shimizu |
890ddd |
event->accept();
|
|
Toshihiro Shimizu |
890ddd |
return true;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
return false;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::focusInEvent(QFocusEvent *fe)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
QWidget::focusInEvent(fe);
|
|
Toshihiro Shimizu |
890ddd |
qApp->installEventFilter(this);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//--------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ChennelCurveEditor::focusOutEvent(QFocusEvent *fe)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_currentControlPointIndex = -1;
|
|
Toshihiro Shimizu |
890ddd |
emit focusOut();
|
|
Toshihiro Shimizu |
890ddd |
QWidget::focusOutEvent(fe);
|
|
Toshihiro Shimizu |
890ddd |
qApp->removeEventFilter(this);
|
|
Toshihiro Shimizu |
890ddd |
update();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
// ToneCurveField
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ToneCurveField::ToneCurveField(QWidget *parent, FxHistogramRender *fxHistogramRender)
|
|
Toshihiro Shimizu |
890ddd |
: QWidget(parent), m_toneCurveStackedWidget(0)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
setFixedWidth(368);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
int currentChannelIndex = 0;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
|
Toshihiro Shimizu |
890ddd |
mainLayout->setMargin(0);
|
|
Toshihiro Shimizu |
890ddd |
mainLayout->setSpacing(0);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QStringList channels;
|
|
Toshihiro Shimizu |
890ddd |
channels << "RGBA"
|
|
Toshihiro Shimizu |
890ddd |
<< "RGB"
|
|
Toshihiro Shimizu |
890ddd |
<< "Red"
|
|
Toshihiro Shimizu |
890ddd |
<< "Green"
|
|
Toshihiro Shimizu |
890ddd |
<< "Blue"
|
|
Toshihiro Shimizu |
890ddd |
<< "Alpha";
|
|
Toshihiro Shimizu |
890ddd |
int channelCount = channels.size();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//lista canali: label+comboBox
|
|
Toshihiro Shimizu |
890ddd |
QWidget *channelListWidget = new QWidget(this);
|
|
Toshihiro Shimizu |
890ddd |
QHBoxLayout *channelListLayout = new QHBoxLayout(channelListWidget);
|
|
Toshihiro Shimizu |
890ddd |
channelListLayout->setMargin(0);
|
|
Toshihiro Shimizu |
890ddd |
channelListLayout->setSpacing(0);
|
|
Toshihiro Shimizu |
890ddd |
QLabel *channelLabel = new QLabel(tr("Channel:"), channelListWidget);
|
|
Toshihiro Shimizu |
890ddd |
channelListLayout->addWidget(channelLabel);
|
|
Toshihiro Shimizu |
890ddd |
m_channelListChooser = new QComboBox(channelListWidget);
|
|
Toshihiro Shimizu |
890ddd |
m_channelListChooser->setFixedSize(100, 20);
|
|
Toshihiro Shimizu |
890ddd |
m_channelListChooser->addItems(channels);
|
|
Toshihiro Shimizu |
890ddd |
m_channelListChooser->setCurrentIndex(currentChannelIndex);
|
|
Toshihiro Shimizu |
890ddd |
channelListLayout->addWidget(m_channelListChooser);
|
|
Toshihiro Shimizu |
890ddd |
channelListWidget->setLayout(channelListLayout);
|
|
Toshihiro Shimizu |
890ddd |
mainLayout->addWidget(channelListWidget, 0, Qt::AlignCenter);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//stack widget dei grafi
|
|
Toshihiro Shimizu |
890ddd |
m_toneCurveStackedWidget = new QStackedWidget(this);
|
|
Toshihiro Shimizu |
890ddd |
Histograms *histograms = new Histograms(0, true);
|
|
Toshihiro Shimizu |
890ddd |
fxHistogramRender->setHistograms(histograms);
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < channelCount; i++) {
|
|
Toshihiro Shimizu |
890ddd |
ChennelCurveEditor *c = new ChennelCurveEditor(this, histograms->getHistogramView(i));
|
|
Toshihiro Shimizu |
890ddd |
m_toneCurveStackedWidget->addWidget(c);
|
|
Toshihiro Shimizu |
890ddd |
connect(c, SIGNAL(firstLastXPostionChanged(int, int)), this, SLOT(onFirstLastXPostionChanged(int, int)));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
QWidget *w = new QWidget(this);
|
|
Toshihiro Shimizu |
890ddd |
QHBoxLayout *layout = new QHBoxLayout(w);
|
|
Toshihiro Shimizu |
890ddd |
layout->setMargin(0);
|
|
Toshihiro Shimizu |
890ddd |
layout->setSpacing(0);
|
|
Toshihiro Shimizu |
890ddd |
layout->addWidget(m_toneCurveStackedWidget);
|
|
Toshihiro Shimizu |
890ddd |
w->setLayout(layout);
|
|
Toshihiro Shimizu |
890ddd |
mainLayout->addWidget(w, 0, Qt::AlignHCenter);
|
|
Toshihiro Shimizu |
890ddd |
m_toneCurveStackedWidget->setCurrentIndex(currentChannelIndex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//stack widget degli slider
|
|
Toshihiro Shimizu |
890ddd |
m_sliderStackedWidget = new QStackedWidget(this);
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < channelCount; i++) {
|
|
Toshihiro Shimizu |
890ddd |
IntPairField *intPairSlider = new IntPairField(this);
|
|
Toshihiro Shimizu |
890ddd |
intPairSlider->setFixedHeight(20);
|
|
Toshihiro Shimizu |
890ddd |
intPairSlider->setLabelsEnabled(false);
|
|
Toshihiro Shimizu |
890ddd |
intPairSlider->setRange(0, 255);
|
|
Toshihiro Shimizu |
890ddd |
intPairSlider->setValues(std::make_pair(0, 255));
|
|
Toshihiro Shimizu |
890ddd |
m_sliderStackedWidget->addWidget(intPairSlider);
|
|
Toshihiro Shimizu |
890ddd |
connect(intPairSlider, SIGNAL(valuesChanged(bool)), this, SLOT(sliderValueChanged(bool)));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
mainLayout->addWidget(m_sliderStackedWidget);
|
|
Toshihiro Shimizu |
890ddd |
m_sliderStackedWidget->setCurrentIndex(currentChannelIndex);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
mainLayout->addSpacing(10);
|
|
Toshihiro Shimizu |
890ddd |
m_isLinearCheckBox = new CheckBox(QString("Linear"), this);
|
|
Toshihiro Shimizu |
890ddd |
mainLayout->addWidget(m_isLinearCheckBox, 0, Qt::AlignHCenter);
|
|
Toshihiro Shimizu |
890ddd |
connect(m_isLinearCheckBox, SIGNAL(clicked(bool)), SLOT(setLinearManually(bool)));
|
|
Toshihiro Shimizu |
890ddd |
connect(m_isLinearCheckBox, SIGNAL(toggled(bool)), SLOT(setLinear(bool)));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
connect(m_channelListChooser, SIGNAL(currentIndexChanged(int)), m_toneCurveStackedWidget, SLOT(setCurrentIndex(int)));
|
|
Toshihiro Shimizu |
890ddd |
connect(m_channelListChooser, SIGNAL(currentIndexChanged(int)), m_sliderStackedWidget, SLOT(setCurrentIndex(int)));
|
|
Toshihiro Shimizu |
890ddd |
connect(m_channelListChooser, SIGNAL(currentIndexChanged(int)), this, SIGNAL(currentChannelIndexChanged(int)));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
setLayout(mainLayout);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ToneCurveField::setCurrentChannel(int currentChannel)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
m_channelListChooser->setCurrentIndex(currentChannel);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ChennelCurveEditor *ToneCurveField::getChannelEditor(int channel) const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
ChennelCurveEditor *c = dynamic_cast<chennelcurveeditor *="">(m_toneCurveStackedWidget->widget(channel));</chennelcurveeditor>
|
|
Toshihiro Shimizu |
890ddd |
assert(c);
|
|
Toshihiro Shimizu |
890ddd |
return c;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
ChennelCurveEditor *ToneCurveField::getCurrentChannelEditor() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return getChannelEditor(m_toneCurveStackedWidget->currentIndex());
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
IntPairField *ToneCurveField::getCurrentSlider() const
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
return dynamic_cast<intpairfield *="">(m_sliderStackedWidget->currentWidget());</intpairfield>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ToneCurveField::sliderValueChanged(bool isDragging)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
std::pair<int, int=""> values = getCurrentSlider()->getValues();</int,>
|
|
Toshihiro Shimizu |
890ddd |
getCurrentChannelEditor()->setFirstLastXPosition(values, isDragging);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ToneCurveField::onFirstLastXPostionChanged(int x0, int x1)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
std::pair<int, int=""> values = getCurrentSlider()->getValues();</int,>
|
|
Toshihiro Shimizu |
890ddd |
if (values.first != x0 || values.second != x1)
|
|
Toshihiro Shimizu |
890ddd |
getCurrentSlider()->setValues(std::make_pair(x0, x1));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ToneCurveField::setIsLinearCheckBox(bool isChecked)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
if (m_isLinearCheckBox->isChecked() == isChecked)
|
|
Toshihiro Shimizu |
890ddd |
return;
|
|
Toshihiro Shimizu |
890ddd |
m_isLinearCheckBox->setChecked(isChecked);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ToneCurveField::setLinear(bool isLinear)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
int i;
|
|
Toshihiro Shimizu |
890ddd |
for (i = 0; i < m_sliderStackedWidget->count(); i++)
|
|
Toshihiro Shimizu |
890ddd |
getChannelEditor(i)->setLinear(isLinear);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
void ToneCurveField::setLinearManually(bool isLinear)
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Toshihiro Shimizu |
890ddd |
emit isLinearChanged(isLinear);
|
|
Toshihiro Shimizu |
890ddd |
}
|