diff options
| author | Johannes Hofmann <Johannes.Hofmann@gmx.de> | 2008-09-07 17:26:28 +0200 |
|---|---|---|
| committer | Johannes Hofmann <Johannes.Hofmann@gmx.de> | 2008-09-07 17:26:28 +0200 |
| commit | 7be4bae40736f364d65cfb56067203451da053a0 (patch) | |
| tree | abd21d91cfcaa3fa5cc1621b2467502e3806f6e5 | |
| parent | 23efce14f047a27f99aa05b8c3596e198d972c19 (diff) | |
finish pnmcurvedit
| -rw-r--r-- | configure.ac | 13 | ||||
| -rw-r--r-- | src/CurveEditor.H | 38 | ||||
| -rw-r--r-- | src/CurveEditor.cxx | 185 | ||||
| -rw-r--r-- | src/Makefile.am | 9 | ||||
| -rw-r--r-- | src/pnmcurvedit.cxx | 46 |
5 files changed, 289 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac index 035d50e..df5f9e0 100644 --- a/configure.ac +++ b/configure.ac @@ -13,8 +13,10 @@ LDFLAGS="-g $LDFLAGS" # Checks for programs. AC_PROG_CC +AC_PROG_CXX AC_LANG_C +AC_LANG_CPLUSPLUS # Checks for libraries. @@ -41,7 +43,18 @@ if test "x$GSLCONFIG" = x; then fi CFLAGS="`$GSLCONFIG --cflags` $CFLAGS" +CXXFLAGS="`$GSLCONFIG --cflags` $CFLAGS" LIBS="`$GSLCONFIG --libs` $LIBS" +# Check for fltk +AC_PATH_PROG(FLTKCONFIG,fltk-config) +if test "x$FLTKCONFIG" = x; then + echo "fltk-config not found" + exit 1 +fi + +CXXFLAGS="`$FLTKCONFIG --cflags` $CXXFLAGS" +LIBS="`$FLTKCONFIG --ldflags` $LIBS" + AC_CONFIG_FILES([Makefile src/Makefile]) AC_OUTPUT diff --git a/src/CurveEditor.H b/src/CurveEditor.H new file mode 100644 index 0000000..bebadd0 --- /dev/null +++ b/src/CurveEditor.H @@ -0,0 +1,38 @@ +// +// Copyright 2008 Johannes Hofmann <Johannes.Hofmann@gmx.de> +// +// This software may be used and distributed according to the terms +// of the GNU General Public License, incorporated herein by reference. + +#ifndef CurveEditor_H +#define CurveEditor_H + +#include <FL/Fl_Widget.H> +#include <gsl/gsl_spline.h> + +class CurveEditor : public Fl_Widget { + private: + double *X, *Y; + int n; + int marked_point; + Fl_Callback *cb; + void *cb_data; + gsl_interp_accel *acc; + gsl_spline *spline; + + public: + CurveEditor(int _x, int _y, int _w, int _h); + + int add_point(double _x, double _y); + void init(); + void clear(); + void move_point(int i, double _x, double _y); + int get_n() {return n;}; + void get_point(int i, double *_x, double *_y); + void remove_point(int i); + void draw(); + int handle(int e); + void callback(Fl_Callback *_cb, void *d) {cb = _cb; cb_data = d;}; +}; + +#endif diff --git a/src/CurveEditor.cxx b/src/CurveEditor.cxx new file mode 100644 index 0000000..a0f4057 --- /dev/null +++ b/src/CurveEditor.cxx @@ -0,0 +1,185 @@ +// +// Copyright 2008 Johannes Hofmann <Johannes.Hofmann@gmx.de> +// +// This software may be used and distributed according to the terms +// of the GNU General Public License, incorporated herein by reference. + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include <FL/Fl.H> +#include <FL/fl_draw.H> + +#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) { + + X = Y = NULL; + marked_point = -1; + cb = NULL; + cb_data = NULL; + n = 0; + acc = gsl_interp_accel_alloc(); + spline = NULL; +} + +void +CurveEditor::draw() { + double step = 1.0 / w() / 2; + + fl_color(FL_BLACK); + fl_rectf(x(), y(), w(), h()); + + fl_color(FL_GRAY); + fl_line_style(FL_DASH); + fl_xyline(x(), y() + h() / 2, x() + w()); + fl_yxline(x() + w() / 2, y(), y() + h()); + + if (n < 3) return; + + fl_push_clip(x(), y(), w(), h()); + fl_color(FL_WHITE); + fl_line_style(FL_SOLID); + fl_begin_line(); + for (double _x = 0.0; _x <= 1.0; _x = _x + step) { + 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((int) rint(x() + w() * X[i] - 2), + (int) rint(y() + h() - h() * Y[i] - 2), 4, 4); + } + + fl_pop_clip(); +} + +int +CurveEditor::handle(int event) { + double mark_x = (double) (Fl::event_x() - x()) / w(); + double mark_y = 1.0 - (double) (Fl::event_y() - y()) / h(); + int i; + + switch (event) { + case FL_PUSH: + Fl::focus(this); + if (Fl::event_button() == 1) { + for (i = 0; i < n; i++) { + if (mark_x >= X[i] - 0.02 && mark_x <= X[i] + 0.02) { + marked_point = i; + move_point(i, mark_x, mark_y); + redraw(); + return 1; + } + } + + marked_point = add_point(mark_x, mark_y); + } + return 1; + case FL_DRAG: + if (marked_point < 0) return 1; + if (marked_point > 0 && mark_x <= X[marked_point - 1] || + marked_point < n - 1 && mark_x >= X[marked_point + 1]) { + remove_point(marked_point); + marked_point = -1; + } else { + move_point(marked_point, mark_x, mark_y); + } + return 1; + case FL_RELEASE: + if (marked_point >= 0) { + if (cb) cb(this, cb_data); + marked_point = -1; + } + return 1; + case FL_FOCUS: + return 1; + case FL_UNFOCUS: + return 0; + } + return 0; +} + +int +CurveEditor::add_point(double _x, double _y) { + int i; + + if (_x < 0.0 || _x > 1.0 || _y < 0.0 || _y > 1.0) { + return -1; + } + + X = (double*) realloc(X, (n + 1) * sizeof(double)); + Y = (double*) realloc(Y, (n + 1) * sizeof(double)); + + for (i = 0; i < n; i++) { + if (_x == X[i]) return -1; + if (_x < X[i]) { + memmove(&X[i + 1], &X[i], sizeof(double) * (n - i)); + memmove(&Y[i + 1], &Y[i], sizeof(double) * (n - i)); + break; + } + } + + X[i] = _x; + Y[i] = _y; + n++; + + init(); + + return i; +} + +void +CurveEditor::init() { + if (n < 3) return; + if (spline) gsl_spline_free(spline); + spline = gsl_spline_alloc(gsl_interp_cspline, n); + gsl_spline_init(spline, X, Y, n); + redraw(); +} + +void +CurveEditor::move_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(); +} + +void +CurveEditor::remove_point(int i) { + if (i < 0 || i >= n) return; + + memmove(&X[i], &X[i + 1], sizeof(double) * (n - i)); + memmove(&Y[i], &Y[i + 1], sizeof(double) * (n - i)); + n--; + init(); +} + +void +CurveEditor::get_point(int i, double *_x, double *_y) { + if (i < 0 || i >= n) return; + + *_x = X[i]; + *_y = Y[i]; +} + +void CurveEditor::clear() { + if (X) free(X); + if (Y) free(Y); + + X = Y = NULL; + n = 0; +} diff --git a/src/Makefile.am b/src/Makefile.am index ddfb6b5..4c8793c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,8 +1,13 @@ -bin_PROGRAMS = pnmcurve +bin_PROGRAMS = pnmcurve pnmcurvedit pnmcurve_SOURCES = \ pnmcurve.c \ pnm.c +pnmcurvedit_SOURCES = \ + CurveEditor.cxx \ + pnmcurvedit.cxx + noinst_HEADERS = \ - pnm.h + pnm.h \ + CurveEditor.H diff --git a/src/pnmcurvedit.cxx b/src/pnmcurvedit.cxx new file mode 100644 index 0000000..bb93099 --- /dev/null +++ b/src/pnmcurvedit.cxx @@ -0,0 +1,46 @@ +// +// Copyright 2008 Johannes Hofmann <Johannes.Hofmann@gmx.de> +// +// This software may be used and distributed according to the terms +// of the GNU General Public License, incorporated herein by reference. + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <math.h> + +#include <FL/Fl.H> +#include <FL/Fl_Double_Window.H> + +#include "CurveEditor.H" + +static CurveEditor *ce; + +static void editor_cb(Fl_Widget* o, void* d) { + double x, y; + + printf("pnmcurve -c "); + for (int i = 0; i<ce->get_n(); i++) { + if (i != 0) + printf(","); + ce->get_point(i, &x, &y); + printf("%g:%g", x, y); + } + printf("\n"); + fflush(stdout); +} + +int +main(int argc, char **argv) { + Fl_Double_Window window(800, 600, "pnmcurvedit"); + ce = new CurveEditor(0, 0, 800, 600); + ce->add_point(0.0, 0.0); + ce->add_point(0.5, 0.4); + ce->add_point(1.0, 1.0); + ce->callback(editor_cb, NULL); + + window.resizable(ce); + window.show(); + + return Fl::run(); +} |
