summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Fl_Search_Chooser.H58
-rw-r--r--src/Fl_Search_Chooser.cxx129
-rw-r--r--src/GipfelWidget.H6
-rw-r--r--src/GipfelWidget.cxx14
-rw-r--r--src/Hill.cxx2
-rw-r--r--src/Makefile.am4
-rw-r--r--src/Panorama.H6
-rw-r--r--src/Panorama.cxx43
-rw-r--r--src/gipfel.cxx29
9 files changed, 271 insertions, 20 deletions
diff --git a/src/Fl_Search_Chooser.H b/src/Fl_Search_Chooser.H
new file mode 100644
index 0000000..6bb71fe
--- /dev/null
+++ b/src/Fl_Search_Chooser.H
@@ -0,0 +1,58 @@
+//
+// "$Id: Fl_Value_Dial.H,v 1.2 2005/05/18 11:34:30 hofmann Exp $"
+//
+// Value dial header file for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2004 by Bill Spitzak and others.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+// Please report all bugs and problems to "fltk-bugs@fltk.org".
+//
+
+#ifndef FL_SEARCH_CHOOSER_H
+#define FL_SEARCH_CHOOSER_H
+
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Select_Browser.H>
+#include <FL/Fl_Input.H>
+
+class Fl_Search_Browser : public Fl_Select_Browser {
+ public:
+
+ Fl_Search_Browser(int X, int Y, int W, int H, const char *c):Fl_Select_Browser(X,Y,W,H,c){};
+
+ int find_prefix(const char *p);
+ private:
+ int find_prefix(const char *p, int s, int e);
+};
+
+class Fl_Search_Chooser {
+ private:
+ public:
+ Fl_Window *w;
+ Fl_Search_Browser *sb;
+
+ Fl_Search_Chooser(const char *title);
+ ~Fl_Search_Chooser();
+
+ void add(const char *t, void *d);
+ void *data();
+ void show();
+ int shown();
+};
+
+#endif
diff --git a/src/Fl_Search_Chooser.cxx b/src/Fl_Search_Chooser.cxx
new file mode 100644
index 0000000..bfcf7fb
--- /dev/null
+++ b/src/Fl_Search_Chooser.cxx
@@ -0,0 +1,129 @@
+//
+// Search Chooser widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright by Johannes Hofmann
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU Library General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+//
+//
+
+#include <stdio.h>
+#include <string.h>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Button.H>
+#include "Fl_Search_Chooser.H"
+
+int
+Fl_Search_Browser::find_prefix(const char *p) {
+ int i = find_prefix(p, 1, size());
+ if (i == -1) {
+ return 1;
+ } else {
+ deselect();
+ middleline(i);
+ select(i);
+ return 0;
+ }
+};
+
+int
+Fl_Search_Browser::find_prefix(const char *p, int s, int e) {
+ if (s < 0 || e > size() || s > e) {
+ fprintf(stderr, "Invalid search range %d %d\n", s, e);
+ return 1;
+ } else if (e - s <= 1) {
+ if (strncasecmp(p, text(s), strlen(p)) == 0) {
+ return s;
+ } else if (strncasecmp(p, text(e), strlen(p)) == 0){
+ return e;
+ } else {
+ return -1;
+ }
+ } else {
+ int med = s + (e - s) / 2;
+ if (strncasecmp(p, text(med), strlen(p)) > 0) {
+ return find_prefix(p, med, e);
+ } else {
+ return find_prefix(p, s, med);
+ }
+ }
+}
+
+
+static void input_cb(Fl_Input* in, void*c) {
+ Fl_Search_Browser *sb = ((Fl_Search_Chooser *) c)->sb;
+ sb->find_prefix(in->value());
+}
+
+
+static void ok_cb(Fl_Input* in, void*c) {
+ Fl_Search_Chooser *sc = (Fl_Search_Chooser *) c;
+ sc->w->hide();
+}
+
+
+static void cancel_cb(Fl_Input* in, void*c) {
+ Fl_Search_Chooser *sc = (Fl_Search_Chooser *) c;
+ sc->sb->deselect();
+ sc->w->hide();
+}
+
+Fl_Search_Chooser::Fl_Search_Chooser(const char *title) {
+ w = new Fl_Window(320, 320, title?title:"Choose");
+ Fl_Group *g = new Fl_Group(10, 10, w->w() - 10, w->h() - 10);
+ sb = new Fl_Search_Browser(g->x(), g->y(), g->w() , g->h() - 100, NULL);
+ sb->type(FL_HOLD_BROWSER);
+ Fl_Input *in = new Fl_Input(g->x(), g->h() - 80, g->w()-10, 20);
+ in->callback((Fl_Callback*) input_cb, this);
+ in->when(FL_WHEN_CHANGED);
+ Fl_Button *cancel_b = new Fl_Button(g->w()-200, g->h()-30, 80, 20, "Cancel");
+ cancel_b->callback((Fl_Callback*) cancel_cb, this);
+ Fl_Button *ok_b = new Fl_Button(g->w()-100, g->h()-30, 80, 20, "Ok");
+ ok_b->callback((Fl_Callback*) ok_cb, this);
+ g->end();
+ w->end();
+}
+
+Fl_Search_Chooser::~Fl_Search_Chooser() {
+ delete sb;
+ delete w;
+}
+
+void
+Fl_Search_Chooser::add(const char *t, void *d) {
+ sb->add(t, d);
+}
+
+void *
+Fl_Search_Chooser::data() {
+ int v = sb->value();
+ if (v) {
+ return sb->data(v);
+ } else {
+ return NULL;
+ }
+}
+
+void
+Fl_Search_Chooser::show() {
+ w->show();
+}
+
+int
+Fl_Search_Chooser::shown() {
+ return w->shown();
+}
+
diff --git a/src/GipfelWidget.H b/src/GipfelWidget.H
index c1b2b86..3fdab77 100644
--- a/src/GipfelWidget.H
+++ b/src/GipfelWidget.H
@@ -63,6 +63,8 @@ class GipfelWidget : public Fl_Widget {
int set_viewpoint(const char *pos);
+ void set_viewpoint(const Hill *m);
+
void set_center_angle(double a);
void set_nick_angle(double a);
@@ -100,7 +102,9 @@ class GipfelWidget : public Fl_Widget {
Projection_t get_projection();
void set_projection(Projection_t p);
-
+
+ Hills *get_mountains();
+
int comp_params();
int guess();
diff --git a/src/GipfelWidget.cxx b/src/GipfelWidget.cxx
index 318d387..b1b677b 100644
--- a/src/GipfelWidget.cxx
+++ b/src/GipfelWidget.cxx
@@ -37,8 +37,8 @@
#include <FL/Fl_Shared_Image.H>
#include <FL/Fl_JPEG_Image.H>
#include <FL/fl_draw.H>
-#include <FL/x.H>
+#include "Fl_Search_Chooser.H"
#include "util.h"
#include "GipfelWidget.H"
@@ -243,6 +243,13 @@ GipfelWidget::set_viewpoint(const char *pos) {
return r;
}
+void
+GipfelWidget::set_viewpoint(const Hill *m) {
+ pan->set_viewpoint(m);
+ set_labels(pan->get_visible_mountains());
+ update_menuitems(pan->get_close_mountains());
+}
+
static void
draw_flag(int x, int y, char *s) {
Fl_Color c = fl_color();
@@ -606,6 +613,11 @@ GipfelWidget::set_view_height(double v) {
redraw();
}
+Hills*
+GipfelWidget::get_mountains() {
+ return pan->get_mountains();
+}
+
int
GipfelWidget::comp_params() {
if (m1 == NULL || m2 == NULL) {
diff --git a/src/Hill.cxx b/src/Hill.cxx
index 9c9329b..7910986 100644
--- a/src/Hill.cxx
+++ b/src/Hill.cxx
@@ -213,7 +213,7 @@ comp_mountains_name(const void *n1, const void *n2) {
Hill *m2 = *(Hill **)n2;
if (m1 && m2) {
- return strcmp(m1->name, m2->name);
+ return strcasecmp(m1->name, m2->name);
} else {
return 0;
}
diff --git a/src/Makefile.am b/src/Makefile.am
index a52d327..8687c95 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,7 +9,8 @@ gipfel_SOURCES = \
ProjectionTangential.cxx \
ProjectionSphaeric.cxx \
Hill.cxx \
- Fl_Value_Dial.cxx
+ Fl_Value_Dial.cxx \
+ Fl_Search_Chooser.cxx
noinst_HEADERS = \
GipfelWidget.H \
@@ -19,4 +20,5 @@ noinst_HEADERS = \
ProjectionSphaeric.H \
Hill.H \
Fl_Value_Dial.H \
+ Fl_Search_Chooser.H \
util.h
diff --git a/src/Panorama.H b/src/Panorama.H
index fe8d41c..fe5b989 100644
--- a/src/Panorama.H
+++ b/src/Panorama.H
@@ -45,7 +45,7 @@ class Panorama {
Projection *proj;
Projection_t projection_type;
- int get_pos(const char *name, double *phi, double *lam, double *height);
+ Hill * get_pos(const char *name);
void update_angles();
@@ -90,8 +90,12 @@ class Panorama {
int set_viewpoint(const char *pos);
+ void set_viewpoint(const Hill *m);
+
void set_height_dist_ratio(double r);
+ Hills * get_mountains();
+
Hills * get_close_mountains();
Hills * get_visible_mountains();
diff --git a/src/Panorama.cxx b/src/Panorama.cxx
index e07d0a8..1643080 100644
--- a/src/Panorama.cxx
+++ b/src/Panorama.cxx
@@ -93,20 +93,40 @@ Panorama::remove_trackpoints() {
int
Panorama::set_viewpoint(const char *name) {
- if (get_pos(name, &view_phi, &view_lam, &view_height) != 1) {
+ Hill *m = get_pos(name);
+ if (m == NULL) {
fprintf(stderr, "Could not find exactly one entry for %s.\n");
return 1;
}
+ set_viewpoint(m);
+ return 0;
+}
+
+void
+Panorama::set_viewpoint(const Hill *m) {
+ if (m == NULL) {
+ return;
+ }
+
+ view_phi = m->phi;
+ view_lam = m->lam;
+ view_height = m->height;
+
+
if (view_name) {
free(view_name);
}
- view_name = strdup(name);
+ view_name = strdup(m->name);
update_angles();
+}
- return 0;
+
+Hills *
+Panorama::get_mountains() {
+ return mountains;
}
Hills *
@@ -337,33 +357,28 @@ Panorama::get_projection() {
return projection_type;
}
-int
-Panorama::get_pos(const char *name, double *phi, double *lam, double *height) {
+Hill *
+Panorama::get_pos(const char *name) {
int i;
int found = 0;
double p, l, h;
- Hill *m;
+ Hill *m, *ret;
for (i=0; i<mountains->get_num(); i++) {
m = mountains->get(i);
if (strcmp(m->name, name) == 0) {
- p = m->phi;
- l = m->lam;
- h = m->height;
-
+ ret = m;
fprintf(stderr, "Found matching entry: %s (%fm)\n", m->name, m->height);
found++;
}
}
if (found == 1) {
- *phi = p;
- *lam = l;
- *height = h;
+ return ret;
}
- return found;
+ return NULL;
}
void
diff --git a/src/gipfel.cxx b/src/gipfel.cxx
index 07087e6..3c14d47 100644
--- a/src/gipfel.cxx
+++ b/src/gipfel.cxx
@@ -46,6 +46,7 @@
#include <FL/Fl_Value_Slider.H>
#include <FL/Fl_Value_Input.H>
#include "Fl_Value_Dial.H"
+#include "Fl_Search_Chooser.H"
#include "GipfelWidget.H"
@@ -138,6 +139,31 @@ void view_height_cb(Fl_Value_Input* o, void*) {
}
}
+void viewpoint_cb(Fl_Value_Input* o, void*) {
+ if (gipf) {
+ Fl_Search_Chooser *sc = new Fl_Search_Chooser("Choose Viewpoint");
+ Hills *h_sort = new Hills(gipf->get_mountains());
+ h_sort->sort_name();
+
+ for (int i=0; i<h_sort->get_num(); i++) {
+ Hill *m = h_sort->get(i);
+ if (m->flags & (HILL_DUPLICATE | HILL_TRACK_POINT)) {
+ continue;
+ }
+ sc->add(m->name, m);
+ }
+
+ sc->show();
+ while (sc->shown()) {
+ Fl::wait();
+ }
+
+ gipf->set_viewpoint((Hill*) sc->data());
+ delete sc;
+ set_values();
+ }
+}
+
void proj_cb(Fl_Value_Input* o, void*d) {
if (gipf) {
if(d == NULL) {
@@ -171,6 +197,7 @@ void about_cb() {
Fl_Menu_Item menuitems[] = {
{ "&File", 0, 0, 0, FL_SUBMENU },
+ { "&Viewpoint", FL_CTRL + 'v', (Fl_Callback *)viewpoint_cb, 0 },
{ "&Save Image", FL_CTRL + 's', (Fl_Callback *)save_cb, 0 },
{ "Load &Track", FL_CTRL + 't', (Fl_Callback *)track_cb, 0 },
{ "&Quit", FL_CTRL + 'q', (Fl_Callback *)quit_cb, 0 },
@@ -187,7 +214,7 @@ Fl_Menu_Item menuitems[] = {
void usage() {
fprintf(stderr,
- "usage: gipfel -v <viewpoint> -d <datafile> <image>\n"
+ "usage: gipfel [-v <viewpoint>] [-d <datafile>] <image>\n"
" -v <viewpoint> Set point from which the picture was taken.\n"
" This must be a string that unambiguously \n"
" matches the name of an entry in the data file.\n"