diff -r 7cc35bc348cc src/DLD-FUNCTIONS/fltk_backend.cc --- a/src/DLD-FUNCTIONS/fltk_backend.cc Sun Jun 28 08:51:41 2009 +0100 +++ b/src/DLD-FUNCTIONS/fltk_backend.cc Mon Jun 29 23:07:01 2009 +0200 @@ -442,63 +442,116 @@ pixel2status (px0, py0, Fl::event_x (), Fl::event_y ()); if (Fl::event_button () == 1) { - canvas->zoom (true); - Matrix zoom_box (1,4,0); - zoom_box (0) = px0; - zoom_box (1) = py0; - zoom_box (2) = Fl::event_x (); - zoom_box (3) = Fl::event_y (); - canvas->set_zoom_box (zoom_box); - canvas->redraw_overlay (); + // XXX: These limits are hard-coded because I couldn't figure out + // XXX: how to get them from the axes + const double minx = 0, maxx = 10, miny = 0, maxy = 10; + + graphics_object ax = gh_manager::get_object (fp.get_currentaxes ()); + if (ax && ax.isa ("axes")) + { + axes::properties& ap = dynamic_cast (ax.get_properties ()); + + // Get current axes limits (FIXME: Handle 3D) + // FIXME: Do we need error checking here? + Matrix xlim = ap.get_xlim ().matrix_value (); + Matrix ylim = ap.get_ylim ().matrix_value (); + + double x0, y0, x1, y1; + pixel2pos (px0, py0, x0, y0); + pixel2pos (Fl::event_x (), Fl::event_y (), x1, y1); + px0 = Fl::event_x (); + py0 = Fl::event_y (); + + double delta_x = x0 - x1; + if (delta_x > 0) + delta_x = std::min (xlim (1) + delta_x, maxx) - xlim (1); + else + delta_x = std::max (xlim (0) + delta_x, minx) - xlim (0); + xlim (0) = xlim (0) + delta_x; + xlim (1) = xlim (1) + delta_x; + + double delta_y = y0 - y1; + if (delta_y > 0) + delta_y = std::min (ylim (1) + delta_y, maxy) - ylim (1); + else + delta_y = std::max (ylim (0) + delta_y, miny) - ylim (0); + ylim (0) = ylim (0) + delta_y; + ylim (1) = ylim (1) + delta_y; + + ap.zoom (xlim, ylim); + mark_modified (); + } return 1; } break; + case FL_MOUSEWHEEL: + { + // Parameter controlling how fast we zoom. FIXME: Should this be user tweakable? + const double zoom_speed = 1.0 / 10.0; + + // XXX: These limits are hard-coded because I couldn't figure out + // XXX: how to get them from the axes + const double minx = 0, maxx = 10, miny = 0, maxy = 10; + + const double max_delta_x = maxx - minx; + const double max_delta_y = maxy - miny; + + graphics_object ax = gh_manager::get_object (fp.get_currentaxes ()); + if (ax && ax.isa ("axes")) + { + axes::properties& ap = dynamic_cast (ax.get_properties ()); + + // Get current axes limits (FIXME: Handle 3D) + // FIXME: Do we need error checking here? + Matrix xlim = ap.get_xlim ().matrix_value (); + Matrix ylim = ap.get_ylim ().matrix_value (); + + const double delta_x = xlim (1) - xlim (0); + const double delta_y = ylim (1) - ylim (0); + + double x1, y1; + pixel2pos (Fl::event_x (), Fl::event_y (), x1, y1); + + const double direction = (Fl::event_dy () > 0) ? 1.0 : -1.0; + const double new_delta_x = + std::min (delta_x + direction * 2.0 * zoom_speed, max_delta_x); + const double new_delta_y = + std::min (delta_y + direction * 2.0 * zoom_speed, max_delta_y); + + const double center_x = xlim (0) + delta_x / 2.0; + const double center_y = ylim (0) + delta_y / 2.0; + double new_center_x = (x1 > center_x) + ? center_x + zoom_speed : center_x - zoom_speed; + double new_center_y = (y1 > center_y) + ? center_y + zoom_speed : center_y - zoom_speed; + + if (new_center_x + new_delta_x / 2.0 > maxx) + new_center_x = maxx - new_delta_x / 2.0; + if (new_center_x - new_delta_x / 2.0 < minx) + new_center_x = minx + new_delta_x / 2.0; + + if (new_center_y + new_delta_y / 2.0 > maxy) + new_center_y = maxy - new_delta_y / 2.0; + if (new_center_y - new_delta_y / 2.0 < minx) + new_center_y = miny + new_delta_y / 2.0; + + xlim (0) = new_center_x - new_delta_x / 2.0; + xlim (1) = new_center_x + new_delta_x / 2.0; + ylim (0) = new_center_y - new_delta_y / 2.0; + ylim (1) = new_center_y + new_delta_y / 2.0; + + ap.zoom (xlim, ylim); + mark_modified (); + } + } + return 1; + case FL_RELEASE: if (Fl::event_button () == 1) { - // end of drag -- zoom - if (canvas->zoom ()) - { - canvas->zoom (false); - double x0,y0,x1,y1; - graphics_object ax = - gh_manager::get_object (fp.get_currentaxes ()); - if (ax && ax.isa ("axes")) - { - axes::properties& ap = - dynamic_cast (ax.get_properties ()); - pixel2pos (px0, py0, x0, y0); - pixel2pos (Fl::event_x (), Fl::event_y (), x1, y1); - Matrix xl (1,2,0); - Matrix yl (1,2,0); - if (x0 < x1) - { - xl(0) = x0; - xl(1) = x1; - } - else - { - xl(0) = x1; - xl(1) = x0; - } - - if (y0 < y1) - { - yl(0) = y0; - yl(1) = y1; - } - else - { - yl(0) = y1; - yl(1) = y0; - } - ap.zoom (xl, yl); - mark_modified (); - } - } // one click -- select axes - else if ( Fl::event_clicks () == 0) + if ( Fl::event_clicks () == 0) { std::cout << "ca="<< h0.value ()<<"\n"; if (h0.ok ())