The first point of the Flat curve editor was misbehaving when using the Shift modifier key

This commit is contained in:
Hombre
2013-10-06 17:33:36 +02:00
parent 0d71e1f74e
commit a101e04371
4 changed files with 83 additions and 63 deletions

View File

@@ -83,14 +83,27 @@ void MyCurve::notifyListener () {
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 (distY < snapToMinDist) {
snapToMinDist = distY;
snapToVal = testedVal;
if (dist < 0.) dist = -dist;
if (dist < snapToMinDistX) {
snapToMinDistX = dist;
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 false;

View File

@@ -28,30 +28,34 @@
#include "guiutils.h"
#include "options.h"
#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_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 SQUARE 2 /* half length of the square shape of the tangent handles */
#define MIN_DISTANCE 5 /* min distance between control points */
#define GRAPH_SIZE 200 /* size of the curve editor graphic */
#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_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 SQUARE 2 /** half length of the square shape of the tangent handles */
#define MIN_DISTANCE 5 /** min distance between control points */
#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 {
CT_Flat,
CT_Diagonal
};
/** @brief Tells the type of element that the points snaps to
*/
enum SnapToType {
ST_None,
ST_Identity, // Point snapped to the identity curve
ST_Neighbors // Point snapped to the neighbor points
ST_None, /// The point is not snapped
ST_Identity, /// Point snapped to the identity curve
ST_Neighbors /// Point snapped to the neighbor points
};
enum ResizeState {
RS_Pending = 1, // Resize has to occure
RS_Done = 2, // Resize has been done
RS_Force = 4 // Resize has to occure even without CONFIGURE event
RS_Pending = 1, /// Resize has to occurs
RS_Done = 2, /// Resize has been done
RS_Force = 4 /// Resize has to occurs even without CONFIGURE event
};
class MyCurveIdleHelper;
@@ -65,17 +69,17 @@ class MyCurve : public Gtk::DrawingArea, public BackBuffer, public ColorCaller {
ColoredBar *leftBar;
ColoredBar *bottomBar;
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 prevGraphW, prevGraphH; // previous inner width and height of the editor
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
Gdk::ModifierType mod_type;
int cursorX; // X coordinate in the graph of the cursor
int cursorY; // Y 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
std::vector< Point<float> > point;
std::vector< Point<float> > upoint;
std::vector< Point<float> > lpoint;
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)
* -3 : maximum value
* -2 : identity value
@@ -85,15 +89,16 @@ class MyCurve : public Gtk::DrawingArea, public BackBuffer, public ColorCaller {
*/
int snapToElmt;
bool snapTo;
double snapToMinDist;
double snapToVal;
double snapToMinDistX, snapToMinDistY;
double snapToValX, snapToValY;
MyCurveIdleHelper* mcih;
enum ResizeState sized;
bool curveIsDirty;
virtual std::vector<double> get_vector (int veclen) = 0;
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
int calcDimensions ();

View File

@@ -494,8 +494,8 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) {
snapToElmt = -100;
if (curve.type == DCT_Linear || curve.type == DCT_Spline || curve.type == DCT_NURBS) {
snapToMinDist = 10.;
snapToVal = 0.;
snapToMinDistY = snapToMinDistX = 10.;
snapToValY = snapToValX = 0.;
snapToElmt = -100;
// get the pointer position
@@ -578,21 +578,21 @@ bool MyDiagonalCurve::handleEvents (GdkEvent* event) {
double ratio = (curve.x[grab_point]-prevX)/(nextX-prevX);
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) {
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)) {
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 (snapCoordinate(curve.x[grab_point], ugpY)) snapToElmt = -2;
if (snapCoordinate(0.0, ugpY)) snapToElmt = -1;
if (snapCoordinateY(1.0, ugpY)) snapToElmt = -3;
if (snapCoordinateY(curve.x[grab_point], ugpY)) snapToElmt = -2;
if (snapCoordinateY(0.0, ugpY)) snapToElmt = -1;
curve.y[grab_point] = snapToVal;
curve.y[grab_point] = snapToValY;
}
else {
// nextPosY is in the bounds

View File

@@ -654,8 +654,8 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) {
int previous_lit_point = lit_point;
enum MouseOverAreas prevArea = area;
snapToMinDist = 10.;
snapToVal = 0.;
snapToMinDistY = snapToMinDistX = 10.;
snapToValY = snapToValX = 0.;
snapToElmt = -100;
// get the pointer position
@@ -788,11 +788,12 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) {
ugpX -= deltaX*3;
ugpX = CLAMP(ugpX, 0., 1.);
if (snapTo) {
snapCoordinate(0.0, ugpX);
snapCoordinate(0.35, ugpX);
snapCoordinate(0.5, ugpX);
snapCoordinate(1.0, ugpX);
curve.leftTangent[lit_point] = snapToVal;
// since this handle can only move in one direction, we can reuse the snapCoordinateX mechanism
snapCoordinateX(0.0, ugpX);
snapCoordinateX(0.35, ugpX);
snapCoordinateX(0.5, ugpX);
snapCoordinateX(1.0, ugpX);
curve.leftTangent[lit_point] = snapToValX;
}
else {
curve.leftTangent[lit_point] = ugpX;
@@ -813,11 +814,12 @@ bool MyFlatCurve::handleEvents (GdkEvent* event) {
ugpX += deltaX*3;
ugpX = CLAMP(ugpX, 0., 1.);
if (snapTo) {
snapCoordinate(0.0, ugpX);
snapCoordinate(0.35, ugpX);
snapCoordinate(0.5, ugpX);
snapCoordinate(1.0, ugpX);
curve.rightTangent[lit_point] = snapToVal;
// since this handle can only move in one direction, we can reuse the snapCoordinateX mechanism
snapCoordinateX(0.0, ugpX);
snapCoordinateX(0.35, ugpX);
snapCoordinateX(0.5, ugpX);
snapCoordinateX(1.0, ugpX);
curve.rightTangent[lit_point] = snapToValX;
}
else {
curve.rightTangent[lit_point] = ugpX;
@@ -897,12 +899,12 @@ void MyFlatCurve::movePoint(bool moveX, bool moveY) {
if (periodic) {
if (snapTo) {
if (lit_point==0) {
snapCoordinate(0.0, ugpX);
curve.x[0] = snapToVal;
snapCoordinateX(0.0, ugpX);
curve.x[0] = snapToValX;
}
else if (lit_point==(nbPoints-1)) {
snapCoordinate(1.0, ugpX);
curve.x[nbPoints-1] = snapToVal;
snapCoordinateX(1.0, ugpX);
curve.x[nbPoints-1] = snapToValX;
}
}
else if (lit_point==0 && ugpX<0.) {
@@ -995,27 +997,27 @@ void MyFlatCurve::movePoint(bool moveX, bool moveY) {
if (lit_point == 0) {
int prevP = curve.y.size()-1;
if (snapCoordinate(curve.y[prevP], ugpY)) snapToElmt = prevP;
if (snapCoordinateY(curve.y[prevP], ugpY)) snapToElmt = prevP;
}
else {
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 (lit_point == (curve.y.size()-1)) {
if (snapCoordinate(curve.y[0], ugpY)) snapToElmt = 0;
if (snapCoordinateY(curve.y[0], ugpY)) snapToElmt = 0;
}
else {
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 (snapCoordinate(0.5, ugpY)) snapToElmt = -2;
if (snapCoordinate(0.0, ugpY)) snapToElmt = -1;
if (snapCoordinateY(1.0, ugpY)) snapToElmt = -3;
if (snapCoordinateY(0.5, ugpY)) snapToElmt = -2;
if (snapCoordinateY(0.0, ugpY)) snapToElmt = -1;
curve.y[lit_point] = snapToVal;
curve.y[lit_point] = snapToValY;
}
// Handling limitations along Y axis
@@ -1153,7 +1155,7 @@ void MyFlatCurve::getMouseOverArea () {
if (curve.x[i] != -1) {
dX = curve.x[i] - preciseCursorX;
absDX = dX>0 ? dX : -dX;
if ((absDX < minDistX) || (absDX == minDistX && dX<0)) {
if (absDX < minDistX) {
minDistX = absDX;
closest_point = i;
lit_point = i;