The first point of the Flat curve editor was misbehaving when using the Shift modifier key
This commit is contained in:
@@ -83,14 +83,27 @@ void MyCurve::notifyListener () {
|
|||||||
listener->curveChanged ();
|
listener->curveChanged ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MyCurve::snapCoordinate(double testedVal, double realVal) {
|
bool MyCurve::snapCoordinateX(double testedVal, double realVal) {
|
||||||
|
|
||||||
double distY = realVal - testedVal;
|
double dist = realVal - testedVal;
|
||||||
|
|
||||||
if (distY < 0.) distY = -distY;
|
if (dist < 0.) dist = -dist;
|
||||||
if (distY < snapToMinDist) {
|
if (dist < snapToMinDistX) {
|
||||||
snapToMinDist = distY;
|
snapToMinDistX = dist;
|
||||||
snapToVal = testedVal;
|
snapToValX = testedVal;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MyCurve::snapCoordinateY(double testedVal, double realVal) {
|
||||||
|
|
||||||
|
double dist = realVal - testedVal;
|
||||||
|
|
||||||
|
if (dist < 0.) dist = -dist;
|
||||||
|
if (dist < snapToMinDistY) {
|
||||||
|
snapToMinDistY = dist;
|
||||||
|
snapToValY = testedVal;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@@ -28,30 +28,34 @@
|
|||||||
#include "guiutils.h"
|
#include "guiutils.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
|
|
||||||
#define RADIUS 3 /* radius of the control points */
|
#define RADIUS 3 /** radius of the control points */
|
||||||
#define CBAR_WIDTH_STD 13 /* width of the colored bar (border included) for standard themes */
|
#define CBAR_WIDTH_STD 13 /** width of the colored bar (border included) for standard themes */
|
||||||
#define CBAR_WIDTH_SLIM 10 /* width of the colored bar (border included) for slim themes */
|
#define CBAR_WIDTH_SLIM 10 /** width of the colored bar (border included) for slim themes */
|
||||||
#define CBAR_MARGIN 2 /* spacing between the colored bar and the graph */
|
#define CBAR_MARGIN 2 /** spacing between the colored bar and the graph */
|
||||||
#define SQUARE 2 /* half length of the square shape of the tangent handles */
|
#define SQUARE 2 /** half length of the square shape of the tangent handles */
|
||||||
#define MIN_DISTANCE 5 /* min distance between control points */
|
#define MIN_DISTANCE 5 /** min distance between control points */
|
||||||
#define GRAPH_SIZE 200 /* size of the curve editor graphic */
|
#define GRAPH_SIZE 200 /** size of the curve editor graphic */
|
||||||
|
|
||||||
// For compatibility and simplicity reason, order shouldn't change, and must be identical to the order specified in the curveType widget
|
/** @brief Flat or Diagonal curve type
|
||||||
|
For compatibility and simplicity reason, order shouldn't change, and must be identical to the order specified in the curveType widget
|
||||||
|
*/
|
||||||
enum CurveType {
|
enum CurveType {
|
||||||
CT_Flat,
|
CT_Flat,
|
||||||
CT_Diagonal
|
CT_Diagonal
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @brief Tells the type of element that the points snaps to
|
||||||
|
*/
|
||||||
enum SnapToType {
|
enum SnapToType {
|
||||||
ST_None,
|
ST_None, /// The point is not snapped
|
||||||
ST_Identity, // Point snapped to the identity curve
|
ST_Identity, /// Point snapped to the identity curve
|
||||||
ST_Neighbors // Point snapped to the neighbor points
|
ST_Neighbors /// Point snapped to the neighbor points
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ResizeState {
|
enum ResizeState {
|
||||||
RS_Pending = 1, // Resize has to occure
|
RS_Pending = 1, /// Resize has to occurs
|
||||||
RS_Done = 2, // Resize has been done
|
RS_Done = 2, /// Resize has been done
|
||||||
RS_Force = 4 // Resize has to occure even without CONFIGURE event
|
RS_Force = 4 /// Resize has to occurs even without CONFIGURE event
|
||||||
};
|
};
|
||||||
|
|
||||||
class MyCurveIdleHelper;
|
class MyCurveIdleHelper;
|
||||||
@@ -65,17 +69,17 @@ class MyCurve : public Gtk::DrawingArea, public BackBuffer, public ColorCaller {
|
|||||||
ColoredBar *leftBar;
|
ColoredBar *leftBar;
|
||||||
ColoredBar *bottomBar;
|
ColoredBar *bottomBar;
|
||||||
CursorShape cursor_type;
|
CursorShape cursor_type;
|
||||||
int graphX, graphY, graphW, graphH; // dimensions of the graphic area, excluding surrounding space for the points of for the colored bar
|
int graphX, graphY, graphW, graphH; /// dimensions of the graphic area, excluding surrounding space for the points of for the colored bar
|
||||||
int prevGraphW, prevGraphH; // previous inner width and height of the editor
|
int prevGraphW, prevGraphH; /// previous inner width and height of the editor
|
||||||
Gdk::ModifierType mod_type;
|
Gdk::ModifierType mod_type;
|
||||||
int cursorX; // X coordinate in the graph of the cursor
|
int cursorX; /// X coordinate in the graph of the cursor
|
||||||
int cursorY; // Y coordinate in the graph of the cursor
|
int cursorY; /// Y coordinate in the graph of the cursor
|
||||||
std::vector< Point<float> > point;
|
std::vector< Point<float> > point;
|
||||||
std::vector< Point<float> > upoint;
|
std::vector< Point<float> > upoint;
|
||||||
std::vector< Point<float> > lpoint;
|
std::vector< Point<float> > lpoint;
|
||||||
bool buttonPressed;
|
bool buttonPressed;
|
||||||
/*
|
/**
|
||||||
* snapToElmt must be interpreted like this:
|
* snapToElmt, which will be used for the Y axis only, must be interpreted like this:
|
||||||
* -100 : no element (default)
|
* -100 : no element (default)
|
||||||
* -3 : maximum value
|
* -3 : maximum value
|
||||||
* -2 : identity value
|
* -2 : identity value
|
||||||
@@ -85,15 +89,16 @@ class MyCurve : public Gtk::DrawingArea, public BackBuffer, public ColorCaller {
|
|||||||
*/
|
*/
|
||||||
int snapToElmt;
|
int snapToElmt;
|
||||||
bool snapTo;
|
bool snapTo;
|
||||||
double snapToMinDist;
|
double snapToMinDistX, snapToMinDistY;
|
||||||
double snapToVal;
|
double snapToValX, snapToValY;
|
||||||
MyCurveIdleHelper* mcih;
|
MyCurveIdleHelper* mcih;
|
||||||
enum ResizeState sized;
|
enum ResizeState sized;
|
||||||
bool curveIsDirty;
|
bool curveIsDirty;
|
||||||
|
|
||||||
virtual std::vector<double> get_vector (int veclen) = 0;
|
virtual std::vector<double> get_vector (int veclen) = 0;
|
||||||
int getGraphMinSize() { return GRAPH_SIZE + RADIUS + 1; }
|
int getGraphMinSize() { return GRAPH_SIZE + RADIUS + 1; }
|
||||||
bool snapCoordinate(double testedVal, double realVal);
|
bool snapCoordinateX(double testedVal, double realVal);
|
||||||
|
bool snapCoordinateY(double testedVal, double realVal);
|
||||||
|
|
||||||
// return value = new requested height
|
// return value = new requested height
|
||||||
int calcDimensions ();
|
int calcDimensions ();
|
||||||
|
@@ -494,8 +494,8 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) {
|
|||||||
snapToElmt = -100;
|
snapToElmt = -100;
|
||||||
if (curve.type == DCT_Linear || curve.type == DCT_Spline || curve.type == DCT_NURBS) {
|
if (curve.type == DCT_Linear || curve.type == DCT_Spline || curve.type == DCT_NURBS) {
|
||||||
|
|
||||||
snapToMinDist = 10.;
|
snapToMinDistY = snapToMinDistX = 10.;
|
||||||
snapToVal = 0.;
|
snapToValY = snapToValX = 0.;
|
||||||
snapToElmt = -100;
|
snapToElmt = -100;
|
||||||
|
|
||||||
// get the pointer position
|
// get the pointer position
|
||||||
@@ -578,21 +578,21 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) {
|
|||||||
double ratio = (curve.x[grab_point]-prevX)/(nextX-prevX);
|
double ratio = (curve.x[grab_point]-prevX)/(nextX-prevX);
|
||||||
double y = (nextY-prevY) * ratio + prevY;
|
double y = (nextY-prevY) * ratio + prevY;
|
||||||
|
|
||||||
if (snapCoordinate(y, ugpY)) snapToElmt = 1000+grab_point;
|
if (snapCoordinateY(y, ugpY)) snapToElmt = 1000+grab_point;
|
||||||
}
|
}
|
||||||
if (grab_point > 0) {
|
if (grab_point > 0) {
|
||||||
int prevP = grab_point-1;
|
int prevP = grab_point-1;
|
||||||
if (snapCoordinate(curve.y[prevP], ugpY)) snapToElmt = prevP;
|
if (snapCoordinateY(curve.y[prevP], ugpY)) snapToElmt = prevP;
|
||||||
}
|
}
|
||||||
if (grab_point < (curve.y.size()-1)) {
|
if (grab_point < (curve.y.size()-1)) {
|
||||||
int nextP = grab_point+1;
|
int nextP = grab_point+1;
|
||||||
if (snapCoordinate(curve.y[nextP], ugpY)) snapToElmt = nextP;
|
if (snapCoordinateY(curve.y[nextP], ugpY)) snapToElmt = nextP;
|
||||||
}
|
}
|
||||||
if (snapCoordinate(1.0, ugpY)) snapToElmt = -3;
|
if (snapCoordinateY(1.0, ugpY)) snapToElmt = -3;
|
||||||
if (snapCoordinate(curve.x[grab_point], ugpY)) snapToElmt = -2;
|
if (snapCoordinateY(curve.x[grab_point], ugpY)) snapToElmt = -2;
|
||||||
if (snapCoordinate(0.0, ugpY)) snapToElmt = -1;
|
if (snapCoordinateY(0.0, ugpY)) snapToElmt = -1;
|
||||||
|
|
||||||
curve.y[grab_point] = snapToVal;
|
curve.y[grab_point] = snapToValY;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// nextPosY is in the bounds
|
// nextPosY is in the bounds
|
||||||
|
@@ -654,8 +654,8 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) {
|
|||||||
int previous_lit_point = lit_point;
|
int previous_lit_point = lit_point;
|
||||||
enum MouseOverAreas prevArea = area;
|
enum MouseOverAreas prevArea = area;
|
||||||
|
|
||||||
snapToMinDist = 10.;
|
snapToMinDistY = snapToMinDistX = 10.;
|
||||||
snapToVal = 0.;
|
snapToValY = snapToValX = 0.;
|
||||||
snapToElmt = -100;
|
snapToElmt = -100;
|
||||||
|
|
||||||
// get the pointer position
|
// get the pointer position
|
||||||
@@ -788,11 +788,12 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) {
|
|||||||
ugpX -= deltaX*3;
|
ugpX -= deltaX*3;
|
||||||
ugpX = CLAMP(ugpX, 0., 1.);
|
ugpX = CLAMP(ugpX, 0., 1.);
|
||||||
if (snapTo) {
|
if (snapTo) {
|
||||||
snapCoordinate(0.0, ugpX);
|
// since this handle can only move in one direction, we can reuse the snapCoordinateX mechanism
|
||||||
snapCoordinate(0.35, ugpX);
|
snapCoordinateX(0.0, ugpX);
|
||||||
snapCoordinate(0.5, ugpX);
|
snapCoordinateX(0.35, ugpX);
|
||||||
snapCoordinate(1.0, ugpX);
|
snapCoordinateX(0.5, ugpX);
|
||||||
curve.leftTangent[lit_point] = snapToVal;
|
snapCoordinateX(1.0, ugpX);
|
||||||
|
curve.leftTangent[lit_point] = snapToValX;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
curve.leftTangent[lit_point] = ugpX;
|
curve.leftTangent[lit_point] = ugpX;
|
||||||
@@ -813,11 +814,12 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) {
|
|||||||
ugpX += deltaX*3;
|
ugpX += deltaX*3;
|
||||||
ugpX = CLAMP(ugpX, 0., 1.);
|
ugpX = CLAMP(ugpX, 0., 1.);
|
||||||
if (snapTo) {
|
if (snapTo) {
|
||||||
snapCoordinate(0.0, ugpX);
|
// since this handle can only move in one direction, we can reuse the snapCoordinateX mechanism
|
||||||
snapCoordinate(0.35, ugpX);
|
snapCoordinateX(0.0, ugpX);
|
||||||
snapCoordinate(0.5, ugpX);
|
snapCoordinateX(0.35, ugpX);
|
||||||
snapCoordinate(1.0, ugpX);
|
snapCoordinateX(0.5, ugpX);
|
||||||
curve.rightTangent[lit_point] = snapToVal;
|
snapCoordinateX(1.0, ugpX);
|
||||||
|
curve.rightTangent[lit_point] = snapToValX;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
curve.rightTangent[lit_point] = ugpX;
|
curve.rightTangent[lit_point] = ugpX;
|
||||||
@@ -897,12 +899,12 @@ void MyFlatCurve::movePoint(bool moveX, bool moveY) {
|
|||||||
if (periodic) {
|
if (periodic) {
|
||||||
if (snapTo) {
|
if (snapTo) {
|
||||||
if (lit_point==0) {
|
if (lit_point==0) {
|
||||||
snapCoordinate(0.0, ugpX);
|
snapCoordinateX(0.0, ugpX);
|
||||||
curve.x[0] = snapToVal;
|
curve.x[0] = snapToValX;
|
||||||
}
|
}
|
||||||
else if (lit_point==(nbPoints-1)) {
|
else if (lit_point==(nbPoints-1)) {
|
||||||
snapCoordinate(1.0, ugpX);
|
snapCoordinateX(1.0, ugpX);
|
||||||
curve.x[nbPoints-1] = snapToVal;
|
curve.x[nbPoints-1] = snapToValX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (lit_point==0 && ugpX<0.) {
|
else if (lit_point==0 && ugpX<0.) {
|
||||||
@@ -995,27 +997,27 @@ void MyFlatCurve::movePoint(bool moveX, bool moveY) {
|
|||||||
|
|
||||||
if (lit_point == 0) {
|
if (lit_point == 0) {
|
||||||
int prevP = curve.y.size()-1;
|
int prevP = curve.y.size()-1;
|
||||||
if (snapCoordinate(curve.y[prevP], ugpY)) snapToElmt = prevP;
|
if (snapCoordinateY(curve.y[prevP], ugpY)) snapToElmt = prevP;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int prevP = lit_point-1;
|
int prevP = lit_point-1;
|
||||||
if (snapCoordinate(curve.y[prevP], ugpY)) snapToElmt = prevP;
|
if (snapCoordinateY(curve.y[prevP], ugpY)) snapToElmt = prevP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (curve.y.size() > 2) {
|
if (curve.y.size() > 2) {
|
||||||
if (lit_point == (curve.y.size()-1)) {
|
if (lit_point == (curve.y.size()-1)) {
|
||||||
if (snapCoordinate(curve.y[0], ugpY)) snapToElmt = 0;
|
if (snapCoordinateY(curve.y[0], ugpY)) snapToElmt = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int nextP = lit_point+1;
|
int nextP = lit_point+1;
|
||||||
if (snapCoordinate(curve.y[nextP], ugpY)) snapToElmt = nextP;
|
if (snapCoordinateY(curve.y[nextP], ugpY)) snapToElmt = nextP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (snapCoordinate(1.0, ugpY)) snapToElmt = -3;
|
if (snapCoordinateY(1.0, ugpY)) snapToElmt = -3;
|
||||||
if (snapCoordinate(0.5, ugpY)) snapToElmt = -2;
|
if (snapCoordinateY(0.5, ugpY)) snapToElmt = -2;
|
||||||
if (snapCoordinate(0.0, ugpY)) snapToElmt = -1;
|
if (snapCoordinateY(0.0, ugpY)) snapToElmt = -1;
|
||||||
|
|
||||||
curve.y[lit_point] = snapToVal;
|
curve.y[lit_point] = snapToValY;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handling limitations along Y axis
|
// Handling limitations along Y axis
|
||||||
@@ -1153,7 +1155,7 @@ void MyFlatCurve::getMouseOverArea () {
|
|||||||
if (curve.x[i] != -1) {
|
if (curve.x[i] != -1) {
|
||||||
dX = curve.x[i] - preciseCursorX;
|
dX = curve.x[i] - preciseCursorX;
|
||||||
absDX = dX>0 ? dX : -dX;
|
absDX = dX>0 ? dX : -dX;
|
||||||
if ((absDX < minDistX) || (absDX == minDistX && dX<0)) {
|
if (absDX < minDistX) {
|
||||||
minDistX = absDX;
|
minDistX = absDX;
|
||||||
closest_point = i;
|
closest_point = i;
|
||||||
lit_point = i;
|
lit_point = i;
|
||||||
|
Reference in New Issue
Block a user