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 (); 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;

View File

@@ -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 ();

View File

@@ -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

View File

@@ -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;