// // Copyright 2008 Johannes Hofmann // // This software may be used and distributed according to the terms // of the GNU General Public License, incorporated herein by reference. #include #include #include #include #include #include "CurveEditor.H" CurveEditor::CurveEditor(int my_x, int my_y, int my_w, int my_h) : Fl_Widget(my_x, my_y, my_w, my_h) { marked_point = -1; n = 0; X = NULL; Y = NULL; acc = gsl_interp_accel_alloc (); spline = NULL; } void CurveEditor::draw() { fl_color(FL_BLACK); fl_rectf(x(), y(), w(), h()); fl_color(FL_WHITE); fl_begin_line(); for (double _x = 0.0; _x < 1.0; _x = _x + 0.01) { double _y = gsl_spline_eval(spline, _x, acc); fl_vertex(x() + _x * w(), y() + h() - h() * _y); } fl_end_line(); for (int i = 0; i < n; i++) { fl_rectf(x() + w() * X[i] - 2, y() + h() - h() * Y[i] - 2, 4, 4); } } int CurveEditor::handle(int event) { int mark_x = Fl::event_x() - x(); int mark_y = Fl::event_y() - y(); switch(event) { case FL_PUSH: if (Fl::event_button() == 1) { for (int i = 0; i < n; i++) { int x_i = (int) rint(X[i] * w()); int y_i = (int) rint(h() - Y[i] * h()); if (mark_x >= x_i - 2 && mark_x <= x_i + 2 && mark_y >= y_i - 2 && mark_y <= y_i + 2) { marked_point = i; redraw(); break; } } } Fl::focus(this); return 1; case FL_DRAG: set_point(marked_point, (double) mark_x / w(), 1.0 - (double) mark_y / h()); return 1; case FL_RELEASE: marked_point = -1; printf("%g,%g", X[0], Y[0]); for (int i = 1; i < n; i++) { printf(";%g,%g", X[i], Y[i]); } printf("\n"); fflush(stdout); return 1; case FL_FOCUS: return 1; case FL_UNFOCUS: return 0; } return 0; } void CurveEditor::add_point(double _x, double _y) { if ((_x < 0.0 || _x > 1.0 || _y < 0.0 || _y > 1.0) || n > 0 && _x <= X[n]) { return; } n++; X = (double*) realloc(X, n * sizeof(double)); Y = (double*) realloc(Y, n * sizeof(double)); X[n - 1] = _x; Y[n - 1] = _y; } void CurveEditor::init() { if (spline) gsl_spline_free(spline); spline = gsl_spline_alloc (gsl_interp_cspline, n); gsl_spline_init (spline, X, Y, n); } void CurveEditor::set_point(int i, double _x, double _y) { if (i >= n || (_x < 0.0 || _x > 1.0 || _y < 0.0 || _y > 1.0) || (i < n - 1 && _x >= X[i + 1]) || (i > 0 && _x <= X[i - 1])) { return; } X[i] = _x; Y[i] = _y; gsl_spline_init (spline, X, Y, n); redraw(); }