# HG changeset patch # User Kai Habel # Date 1279471427 -7200 # Node ID 88dfc9c07de8fa745ba97346bf1d199ea2e94fab # Parent 3140cb7a05a1dc71d21f210e40bcc1fe7ef556e1 [mq]: mouse_rotation diff -r 3140cb7a05a1 -r 88dfc9c07de8 src/ChangeLog --- a/src/ChangeLog Sat Jul 17 19:53:01 2010 -0700 +++ b/src/ChangeLog Sun Jul 18 18:43:47 2010 +0200 @@ -1,3 +1,9 @@ +2010-07-18 Kai Habel + * DLD-FUNCTIONS/fltk_backend.cc: Add mode for mouse rotation. + (view2status): new function + * src/graphics.cc: Remove limitations for zooming and translation. + (axes::properties::rotate_view): new function + 2010-07-17 Rik * DLD-FUNCTIONS/balance.cc, DLD-FUNCTIONS/ccolamd.cc, diff -r 3140cb7a05a1 -r 88dfc9c07de8 src/DLD-FUNCTIONS/fltk_backend.cc --- a/src/DLD-FUNCTIONS/fltk_backend.cc Sat Jul 17 19:53:01 2010 -0700 +++ b/src/DLD-FUNCTIONS/fltk_backend.cc Sun Jul 18 18:43:47 2010 +0200 @@ -69,6 +69,8 @@ const char* help_text = "\ Keyboard Shortcuts\n\ a - autoscale\n\ +p - pan/zoom\n\ +r - rotate\n\ g - toggle grid\n\ \n\ Mouse\n\ @@ -219,8 +221,7 @@ public: plot_window (int xx, int yy, int ww, int hh, figure::properties& xfp) : Fl_Window (xx, yy, ww, hh, "octave"), window_label (), shift (0), - fp (xfp), canvas (0), autoscale (0), togglegrid (0), help (0), - status (0) + fp (xfp), canvas (0), autoscale (0), togglegrid (0), panzoom (0), rotate (0), help (0), status (0) { callback (window_close, static_cast (this)); @@ -245,8 +246,24 @@ "G"); togglegrid->callback (button_callback, static_cast (this)); + panzoom = new + Fl_Button (2 * status_h, + hh - status_h, + status_h, + status_h, + "P"); + panzoom->callback (button_callback, static_cast (this)); + + rotate = new + Fl_Button (3 * status_h, + hh - status_h, + status_h, + status_h, + "R"); + rotate->callback (button_callback, static_cast (this)); + help = new - Fl_Button (2*status_h, + Fl_Button (4 * status_h, hh - status_h, status_h, status_h, @@ -254,7 +271,7 @@ help->callback (button_callback, static_cast (this)); status = new - Fl_Output (3*status_h, + Fl_Output (5 * status_h, hh - status_h, ww > 2*status_h ? ww - status_h : 0, status_h, ""); @@ -279,11 +296,13 @@ status->show (); autoscale->show (); togglegrid->show (); + panzoom->show (); + rotate->show (); set_name (); resizable (canvas); size_range (4*status_h, 2*status_h); - + gui_mode = 1; } ~plot_window (void) @@ -328,6 +347,10 @@ // Mod keys status int shift; + // Interactive Mode + // 1...pan/zoom, 2...rotate/zoom + int gui_mode; + // Figure properties. figure::properties& fp; @@ -355,6 +378,12 @@ if (widg == togglegrid) toggle_grid (); + + if (widg == panzoom) + gui_mode = 1; + + if (widg == rotate) + gui_mode = 2; if (widg == help) fl_message ("%s", help_text); @@ -363,6 +392,8 @@ OpenGL_fltk* canvas; Fl_Button* autoscale; Fl_Button* togglegrid; + Fl_Button* panzoom; + Fl_Button* rotate; Fl_Button* help; Fl_Output* status; @@ -382,7 +413,7 @@ feval ("grid", args); mark_modified (); } - + void pixel2pos (graphics_handle ax, int px, int py, double& xx, double& yy) const { @@ -441,7 +472,8 @@ { double x0, y0, x1, y1; std::stringstream cbuf; - + cbuf.precision(4); + cbuf.width(6); pixel2pos (ax, px0, py0, x0, y0); cbuf << "[" << x0 << ", " << y0 << "]"; if (px1 >= 0) @@ -454,6 +486,24 @@ status->redraw (); } + void view2status (graphics_object ax) + { + if (ax && ax.isa ("axes")) + { + axes::properties& ap = + dynamic_cast (ax.get_properties ()); + std::stringstream cbuf; + cbuf.precision(4); + cbuf.width(6); + Matrix v (1,2,0); + v = ap.get("view").matrix_value(); + cbuf << "[azimuth: " << v(0) << ", elevation: " << v(1) << "]"; + + status->value (cbuf.str ().c_str ()); + status->redraw (); + } + } + void set_currentpoint (int px, int py) { Matrix pos (1,2,0); @@ -624,7 +674,6 @@ break; case FL_DRAG: - pixel2status (ax0, px0, py0, Fl::event_x (), Fl::event_y ()); if (fp.get_windowbuttonmotionfcn ().is_defined ()) { set_currentpoint (Fl::event_x (), Fl::event_y ()); @@ -635,22 +684,37 @@ { if (ax0 && ax0.isa ("axes")) { + if (gui_mode == 1) + pixel2status (ax0, px0, py0, Fl::event_x (), Fl::event_y ()); + else + view2status (ax0); axes::properties& ap = dynamic_cast (ax0.get_properties ()); double x0, y0, x1, y1; + Matrix pos = fp.get_position ().matrix_value (); pixel2pos (ax0, px0, py0, x0, y0); pixel2pos (ax0, Fl::event_x (), Fl::event_y (), x1, y1); + + if (gui_mode == 1) + ap.translate_view (x0 - x1, y0 - y1); + else if (gui_mode == 2) + { + double daz, del; + daz = (Fl::event_x () - px0) / pos(2) * 360; + del = (Fl::event_y () - py0) / pos(3) * 360; + ap.rotate_view (del, daz); + } + px0 = Fl::event_x (); py0 = Fl::event_y (); - - ap.translate_view (x0 - x1, y0 - y1); mark_modified (); } return 1; } else if (Fl::event_button () == 3) { + pixel2status (ax0, px0, py0, Fl::event_x (), Fl::event_y ()); Matrix zoom_box (1,4,0); zoom_box (0) = px0; zoom_box (1) = py0; diff -r 3140cb7a05a1 -r 88dfc9c07de8 src/graphics.cc --- a/src/graphics.cc Sat Jul 17 19:53:01 2010 -0700 +++ b/src/graphics.cc Sun Jul 18 18:43:47 2010 +0200 @@ -4231,12 +4231,6 @@ ylims (0) = y + factor * (ylims (0) - y); ylims (1) = y + factor * (ylims (1) - y); - // Make sure we stay within the range og the plot - xlims (0) = force_in_range (xlims (0), minx, maxx); - xlims (1) = force_in_range (xlims (1), minx, maxx); - ylims (0) = force_in_range (ylims (0), miny, maxy); - ylims (1) = force_in_range (ylims (1), miny, maxy); - zoom (xlims, ylims, push_to_zoom_stack); } @@ -4280,25 +4274,27 @@ double min_pos_y = octave_Inf; get_children_limits (miny, maxy, min_pos_y, kids, 'y'); - // Make sure we don't exceed the borders - if (delta_x > 0) - delta_x = std::min (xlims (1) + delta_x, maxx) - xlims (1); - else - delta_x = std::max (xlims (0) + delta_x, minx) - xlims (0); - xlims (0) = xlims (0) + delta_x; - xlims (1) = xlims (1) + delta_x; - - if (delta_y > 0) - delta_y = std::min (ylims (1) + delta_y, maxy) - ylims (1); - else - delta_y = std::max (ylims (0) + delta_y, miny) - ylims (0); - ylims (0) = ylims (0) + delta_y; - ylims (1) = ylims (1) + delta_y; + xlims (0) += delta_x; + xlims (1) += delta_x; + ylims (0) += delta_y; + ylims (1) += delta_y; zoom (xlims, ylims, false); } void +axes::properties::rotate_view (double delta_el, double delta_az) +{ + Matrix v = get_view ().matrix_value (); + + v (1) += delta_el; + v (0) -= delta_az; + + set_view(v); + update_transform(); +} + +void axes::properties::unzoom (void) { if (zoom_stack.size () >= 4) diff -r 3140cb7a05a1 -r 88dfc9c07de8 src/graphics.h.in --- a/src/graphics.h.in Sat Jul 17 19:53:01 2010 -0700 +++ b/src/graphics.h.in Sun Jul 18 18:43:47 2010 +0200 @@ -2912,6 +2912,7 @@ bool push_to_zoom_stack = true); void zoom (const Matrix& xl, const Matrix& yl, bool push_to_zoom_stack = true); void translate_view (double delta_x, double delta_y); + void rotate_view (double delta_az, double delta_el); void unzoom (void); void clear_zoom_stack (void);