From 53625948c88643dcaf8a6910bfd5710057662ee1 Mon Sep 17 00:00:00 2001 From: Johannes Hofmann Date: Sun, 14 Aug 2005 21:47:42 +0100 Subject: add GUI for viewpoint selection --- src/Fl_Search_Chooser.H | 58 +++++++++++++++++++++ src/Fl_Search_Chooser.cxx | 129 ++++++++++++++++++++++++++++++++++++++++++++++ src/GipfelWidget.H | 6 ++- src/GipfelWidget.cxx | 14 ++++- src/Hill.cxx | 2 +- src/Makefile.am | 4 +- src/Panorama.H | 6 ++- src/Panorama.cxx | 43 +++++++++++----- src/gipfel.cxx | 29 ++++++++++- 9 files changed, 271 insertions(+), 20 deletions(-) create mode 100644 src/Fl_Search_Chooser.H create mode 100644 src/Fl_Search_Chooser.cxx (limited to 'src') 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 +#include +#include + +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 +#include +#include +#include +#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 #include #include -#include +#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; iget_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 #include #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; iget_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 -d \n" + "usage: gipfel [-v ] [-d ] \n" " -v 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" -- cgit v1.2.3