summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohannes Hofmann <Johannes.Hofmann@gmx.de>2008-09-07 17:26:28 +0200
committerJohannes Hofmann <Johannes.Hofmann@gmx.de>2008-09-07 17:26:28 +0200
commit7be4bae40736f364d65cfb56067203451da053a0 (patch)
treeabd21d91cfcaa3fa5cc1621b2467502e3806f6e5 /src
parent23efce14f047a27f99aa05b8c3596e198d972c19 (diff)
finish pnmcurvedit
Diffstat (limited to 'src')
-rw-r--r--src/CurveEditor.H38
-rw-r--r--src/CurveEditor.cxx185
-rw-r--r--src/Makefile.am9
-rw-r--r--src/pnmcurvedit.cxx46
4 files changed, 276 insertions, 2 deletions
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();
+}