Companion curve enhancements (#5947)

* Add point to custom curve using mouse click

* Add more curve enhancements delete and resize points

* add scene constructor
This commit is contained in:
Neil Horne
2018-06-09 11:35:41 +02:00
committed by Bertrand Songis
parent 13c5387dc9
commit d460f005c6
5 changed files with 241 additions and 104 deletions
+89 -4
View File
@@ -122,8 +122,10 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet
ui->curveNameLabel->hide();
}
QGraphicsScene *scene = new QGraphicsScene(ui->curvePreview);
scene = new CustomScene(ui->curvePreview);
scene->setItemIndexMethod(QGraphicsScene::NoIndex);
connect(scene, SIGNAL(newPoint(int, int)), this, SLOT(onSceneNewPoint(int, int)));
ui->curvePreview->setScene(scene);
int numcurves=firmware->getCapability(NumCurves);
int limit;
@@ -212,6 +214,11 @@ Curves::Curves(QWidget * parent, ModelData & model, GeneralSettings & generalSet
addTemplate(tr("Symmetrical f(x)=-f(-x)"), CURVE_COEFF_ENABLE, curveSymmetricalY);
addTemplate(tr("Symmetrical f(x)=f(-x)"), CURVE_COEFF_ENABLE | CURVE_YMID_ENABLE, curveSymmetricalX);
ui->pointSize->setValue(10);
ui->pointSize->setMinimum(3);
ui->pointSize->setMaximum(20);
connect(ui->pointSize, SIGNAL(valueChanged(int)), this, SLOT(onPointSizeEdited()));
disableMouseScrolling();
lock = false;
@@ -292,14 +299,13 @@ void Curves::updateCurve()
Node * nodex = 0;
QColor color;
QGraphicsScene *scene = ui->curvePreview->scene();
scene->clear();
qreal width = scene->sceneRect().width();
qreal height = scene->sceneRect().height();
qreal centerX = scene->sceneRect().left() + width/2; //center X
qreal centerY = scene->sceneRect().top() + height/2; //center Y
qreal centerX = scene->sceneRect().left() + width/2;
qreal centerY = scene->sceneRect().top() + height/2;
QGraphicsSimpleTextItem *ti = scene->addSimpleText(tr("Editing curve %1").arg(currentCurve+1));
ti->setPos(3, 3);
@@ -331,6 +337,8 @@ void Curves::updateCurve()
nodex = new Node();
nodex->setProperty("index", i);
nodex->setColor(colors[currentCurve]);
nodex->setBallSize(ui->pointSize->value());
nodex->setBallHeight(0);
if (model->curves[currentCurve].type == CurveData::CURVE_TYPE_CUSTOM) {
if (i>0 && i<numpoints-1) {
nodex->setFixedX(false);
@@ -349,6 +357,7 @@ void Curves::updateCurve()
connect(nodex, SIGNAL(moved(int, int)), this, SLOT(onNodeMoved(int, int)));
connect(nodex, SIGNAL(focus()), this, SLOT(onNodeFocus()));
connect(nodex, SIGNAL(unfocus()), this, SLOT(onNodeUnfocus()));
connect(nodex, SIGNAL(deleteMe()), this, SLOT(onNodeDelete()));
scene->addItem(nodex);
if (i>0) scene->addItem(new Edge(nodel, nodex));
}
@@ -642,3 +651,79 @@ void Curves::ShowContextMenu(const QPoint& pos) // this is a slot
}
}
}
void Curves::onPointSizeEdited()
{
if (!lock) {
update();
}
}
void Curves::onNodeDelete()
{
int index = sender()->property("index").toInt();
int numpoints = model->curves[currentCurve].count;
if ((model->curves[currentCurve].type == CurveData::CURVE_TYPE_CUSTOM) && (index > 0) && (index < numpoints-1)) {
spny[index]->clearFocus();
for (int i=index+1; i<numpoints; i++) {
model->curves[currentCurve].points[i-1] = model->curves[currentCurve].points[i];
}
numpoints--;
model->curves[currentCurve].points[numpoints].x = 0;
model->curves[currentCurve].points[numpoints].y = 0;
model->curves[currentCurve].count = numpoints;
update();
emit modified();
}
}
void Curves::onSceneNewPoint(int x, int y)
{
if ((model->curves[currentCurve].type == CurveData::CURVE_TYPE_CUSTOM) && (model->curves[currentCurve].count < CPN_MAX_POINTS)) {
int newidx;
int numpoints = model->curves[currentCurve].count;
if (x < model->curves[currentCurve].points[0].x) {
newidx = 0;
}
else if (x > model->curves[currentCurve].points[numpoints - 1].x) {
newidx = numpoints;
}
else {
for (int i=0; i<numpoints; i++) {
if (x < model->curves[currentCurve].points[i].x) {
newidx = i;
break;
}
}
}
numpoints++;
model->curves[currentCurve].count = numpoints;
for (int idx=(numpoints-1); idx>(newidx); idx--) {
model->curves[currentCurve].points[idx] = model->curves[currentCurve].points[idx-1];
}
model->curves[currentCurve].points[newidx].x = x;
model->curves[currentCurve].points[newidx].y = y;
update();
emit modified();
}
}
CustomScene::CustomScene(QGraphicsView * view) :
QGraphicsScene(view)
{
}
void CustomScene::mouseReleaseEvent(QGraphicsSceneMouseEvent * event)
{
if (event->button() == Qt::LeftButton && event->modifiers() == Qt::ControlModifier) {
QRectF rect = sceneRect();
QPointF pos = event->scenePos();
QPointF p;
p.setX(-100 + ((pos.x() - rect.left()) * 200) / rect.width());
p.setY(100 + (rect.top() - pos.y()) * 200 / rect.height());
QGraphicsScene::mouseReleaseEvent(event);
emit newPoint((int)p.x(), (int)p.y());
}
else
QGraphicsScene::mouseReleaseEvent(event);
}
+20 -1
View File
@@ -23,6 +23,8 @@
#include "modeledit.h"
#include "eeprominterface.h"
#include <QGraphicsScene>
#include <QGraphicsView>
enum CopyAction {
CURVE_COPY,
@@ -43,6 +45,20 @@ struct CurveCreatorTemplate {
curveFunction function;
};
class CustomScene : public QGraphicsScene
{
Q_OBJECT
public:
CustomScene(QGraphicsView * view);
signals:
void newPoint(int, int);
protected:
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent * event) override;
};
class Curves : public ModelPanel
{
Q_OBJECT
@@ -67,6 +83,9 @@ class Curves : public ModelPanel
void onNodeUnfocus();
void on_curveType_currentIndexChanged(int index);
void on_curveApply_clicked();
void onSceneNewPoint(int x, int y);
void onPointSizeEdited();
void onNodeDelete();
protected:
virtual void resizeEvent(QResizeEvent *event);
@@ -85,7 +104,7 @@ class Curves : public ModelPanel
void updateCurvePoints();
bool allowCurveType(int points, CurveData::CurveType type);
void setPointY(int i, int x, int y);
CustomScene * scene;
};
#endif // _CURVES_H_
+106 -89
View File
@@ -132,18 +132,18 @@
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="pointsLayout">
<property name="horizontalSpacing">
<number>0</number>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing">
<number>0</number>
</property>
<property name="verticalSpacing">
<number>2</number>
</property>
</layout>
</item>
<item>
@@ -175,17 +175,41 @@
<property name="title">
<string>Curve Creator</string>
</property>
<layout class="QGridLayout" name="gridLayout_76" rowstretch="0,0,0,0,0,0,0,0">
<item row="0" column="1" colspan="3">
<widget class="QComboBox" name="curveType"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="yMidLabel">
<layout class="QGridLayout" name="gridLayout_76" rowstretch="0,0,0,0,0,0,0,0,0,0">
<item row="1" column="0">
<widget class="QLabel" name="curveCoeffLabel">
<property name="text">
<string>Y at X=0</string>
<string>Coefficient</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="curveTypeLabel_2">
<property name="text">
<string>Curve type</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="curveSideLabel">
<property name="text">
<string>Side</string>
</property>
</widget>
</item>
<item row="9" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1" colspan="3">
<widget class="QSpinBox" name="yMax">
<property name="sizePolicy">
@@ -202,6 +226,48 @@
</property>
</widget>
</item>
<item row="3" column="1" colspan="3">
<widget class="QSpinBox" name="yMid">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>-100</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="yMinLabel">
<property name="text">
<string>Y at X=-100</string>
</property>
</widget>
</item>
<item row="5" column="1" colspan="3">
<widget class="QComboBox" name="curveSide">
<item>
<property name="text">
<string>Both</string>
</property>
</item>
<item>
<property name="text">
<string>x&gt;0</string>
</property>
</item>
<item>
<property name="text">
<string>x&lt;0</string>
</property>
</item>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="yMaxLabel">
<property name="text">
@@ -225,23 +291,28 @@
</property>
</widget>
</item>
<item row="5" column="1" colspan="3">
<widget class="QComboBox" name="curveSide">
<item>
<property name="text">
<string>Both</string>
</property>
</item>
<item>
<property name="text">
<string>x&gt;0</string>
</property>
</item>
<item>
<property name="text">
<string>x&lt;0</string>
</property>
</item>
<item row="6" column="0" colspan="4">
<widget class="QPushButton" name="curveApply">
<property name="text">
<string>Apply</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3">
<widget class="QComboBox" name="curveType"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="yMidLabel">
<property name="text">
<string>Y at X=0</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="pointSizeLabel">
<property name="text">
<string>Point size</string>
</property>
</widget>
</item>
<item row="2" column="1" colspan="3">
@@ -260,67 +331,13 @@
</property>
</widget>
</item>
<item row="6" column="0" colspan="4">
<widget class="QPushButton" name="curveApply">
<property name="text">
<string>Apply</string>
</property>
</widget>
<item row="8" column="1" colspan="3">
<widget class="QSpinBox" name="pointSize"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="curveSideLabel">
<property name="text">
<string>Side</string>
</property>
</widget>
</item>
<item row="7" column="0">
<spacer name="verticalSpacer_3">
<item row="7" column="0" colspan="4">
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1" colspan="3">
<widget class="QSpinBox" name="yMid">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimum">
<number>-100</number>
</property>
<property name="maximum">
<number>100</number>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="curveTypeLabel_2">
<property name="text">
<string>Curve type</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="yMinLabel">
<property name="text">
<string>Y at X=-100</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="curveCoeffLabel">
<property name="text">
<string>Coefficient</string>
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
+21 -8
View File
@@ -41,6 +41,7 @@ Node::Node():
fixedX = false;
fixedY = false;
ballSize = DEFAULT_BALL_SIZE;
ballHeight = DEFAULT_BALL_HEIGHT;
}
void Node::addEdge(Edge *edge)
@@ -138,7 +139,7 @@ QRectF Node::boundingRect() const
{
qreal adjust = 2;
return QRectF(-ballSize/2 - adjust, -ballSize/2 - adjust,
ballSize+BALL_HEIGHT + adjust, ballSize+BALL_HEIGHT + adjust);
ballSize+ballHeight + adjust, ballSize+ballHeight + adjust);
}
@@ -153,12 +154,12 @@ void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid
{
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::darkGray);
painter->drawEllipse(-ballSize/2 + BALL_HEIGHT, -ballSize/2 + BALL_HEIGHT, ballSize, ballSize);
painter->drawEllipse(-ballSize/2 + ballHeight, -ballSize/2 + ballHeight, ballSize, ballSize);
QRadialGradient gradient(-BALL_HEIGHT, -BALL_HEIGHT, ballSize/2);
QRadialGradient gradient(-ballHeight, -ballHeight, ballSize/2);
if (option->state & QStyle::State_Sunken) {
gradient.setCenter(BALL_HEIGHT, BALL_HEIGHT);
gradient.setFocalPoint(BALL_HEIGHT, BALL_HEIGHT);
gradient.setCenter(ballHeight, ballHeight);
gradient.setFocalPoint(ballHeight, ballHeight);
gradient.setColorAt(1, nodecolor.light(180));
gradient.setColorAt(0, nodecolor.light(120));
} else {
@@ -189,10 +190,10 @@ QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
if (newX < minX) newX = minX;
if (newX > maxX) newX = maxX;
if (!getFixedX()) {
if (!getFixedX()) {
newPos.setX(((newX+100)*rect.width()/200+rect.left()));
}
emit moved(newX, newY);
return newPos;
}
@@ -220,11 +221,23 @@ void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
update();
bPressed = false;
if (scene()) {
QGraphicsItem::mouseReleaseEvent(event);
emit unfocus();
if (event->button() == Qt::LeftButton && event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier)) {
emit deleteMe();
}
else {
emit unfocus();
}
}
else {
QGraphicsItem::mouseReleaseEvent(event);
}
}
void Node::setBallHeight(int height)
{
ballHeight = height;
}
+5 -2
View File
@@ -24,7 +24,7 @@
#include <QtWidgets>
#define DEFAULT_BALL_SIZE 10
#define BALL_HEIGHT 2
#define DEFAULT_BALL_HEIGHT 2
class Edge;
QT_BEGIN_NAMESPACE
@@ -64,13 +64,15 @@ class Node : public QGraphicsObject
void setMaxX(int val) { maxX = val; }
void setPressed(bool pressed) { bPressed = pressed; }
bool isPressed() const { return bPressed; }
void setColor(const QColor & color);
void setBallHeight(int height);
int geBallHeight() { return ballHeight; }
signals:
void moved(int x, int y);
void focus();
void unfocus();
void deleteMe();
protected:
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
@@ -89,6 +91,7 @@ class Node : public QGraphicsObject
QList<Edge *> edgeList;
QPointF newPos;
QColor nodecolor;
int ballHeight;
};
#endif // _NODE_H_