# HG changeset patch # User Jordi Gutiérrez Hermoso # Date 1282804596 18000 # Node ID db1bc83879ff9bf3f25ecf54c504e50f9caae65f # Parent da90c16fbe8471f91a4cd53e4a9e6b99e404f26b Improvements to FLTK backend rotation * Don't rotate past the top and bottom * Implement __calc_dimensions__ in C++ so that it's available to graphics object ctors * Make rotation the default mode in 3d plots * Replace an instance of m-script __calc_dimensions__ with C++ version diff -r da90c16fbe84 -r db1bc83879ff scripts/ChangeLog --- a/scripts/ChangeLog Wed Aug 25 12:36:23 2010 -0400 +++ b/scripts/ChangeLog Thu Aug 26 01:36:36 2010 -0500 @@ -1,3 +1,10 @@ +2010-08-27 Jordi Gutiérrez Hermoso + + * plot/__go_draw_axes__.m: Remove __calc_dimensions__ and use + defun instead. + * plot/__actual_axis_position__.m: Also remove + __calc_dimensions__ in lieu of defun. + 2010-08-25 Ben Abbott * plot/__go_draw_axes__.m: Revert erroneous portion of changeset diff -r da90c16fbe84 -r db1bc83879ff scripts/plot/__go_draw_axes__.m --- a/scripts/plot/__go_draw_axes__.m Wed Aug 25 12:36:23 2010 -0400 +++ b/scripts/plot/__go_draw_axes__.m Thu Aug 26 01:36:36 2010 -0500 @@ -45,7 +45,8 @@ ymirror = true; endif - nd = __calc_dimensions__ (axis_obj); + nd = __calc_dimensions__ (h); + if (strcmpi (axis_obj.plotboxaspectratiomode, "manual")) pos = __actual_axis_position__ (axis_obj); else @@ -1779,29 +1780,6 @@ endfunction -function nd = __calc_dimensions__ (obj) - kids = obj.children; - nd = 2; - for i = 1:length (kids) - obj = get (kids(i)); - switch (obj.type) - case {"image", "text"} - ## ignore as they - case {"line", "patch"} - if (! isempty (obj.zdata)) - nd = 3; - endif - case "surface" - nd = 3; - case "hggroup" - obj_nd = __calc_dimensions__ (obj); - if (obj_nd == 3) - nd = 3; - endif - endswitch - endfor -endfunction - function __gnuplot_write_data__ (plot_stream, data, nd, parametric, cdata) ## DATA is already transposed. diff -r da90c16fbe84 -r db1bc83879ff scripts/plot/private/__actual_axis_position__.m --- a/scripts/plot/private/__actual_axis_position__.m Wed Aug 25 12:36:23 2010 -0400 +++ b/scripts/plot/private/__actual_axis_position__.m Thu Aug 26 01:36:36 2010 -0500 @@ -31,7 +31,8 @@ ## When using {rltb}margin, Gnuplot does not handle the specified ## aspect ratio properly, so handle it here. - if (__calc_dimensions__ (axis_obj) == 2 || all (mod (axis_obj.view, 90) == 0)) + if (__calc_dimensions__ (axis_obj.parent) == 2 + || all (mod (axis_obj.view, 90) == 0)) aspect_ratio_2d = axis_obj.plotboxaspectratio(1:2); else ## FIXME -- this works for "axis square", but has not been @@ -63,26 +64,3 @@ endfunction -function nd = __calc_dimensions__ (obj) - kids = obj.children; - nd = 2; - for i = 1:length (kids) - obj = get (kids(i)); - switch (obj.type) - case {"image", "text"} - ## ignore as they - case {"line", "patch"} - if (! isempty (obj.zdata)) - nd = 3; - endif - case "surface" - nd = 3; - case "hggroup" - obj_nd = __calc_dimensions__ (obj); - if (obj_nd == 3) - nd = 3; - endif - endswitch - endfor -endfunction - diff -r da90c16fbe84 -r db1bc83879ff src/ChangeLog --- a/src/ChangeLog Wed Aug 25 12:36:23 2010 -0400 +++ b/src/ChangeLog Thu Aug 26 01:36:36 2010 -0500 @@ -1,3 +1,25 @@ +2010-08-27 Jordi Gutiérrez Hermoso + + * graphics.cc (void axes::properties::rotate_view (double + delta_el, double delta_az)) Don't rotate past the top and bottom. + (void axes::properties::update_camera (void)) Fix the view when + rotating to the bottom. + (octave_value calc_dimensions(const graphics_object& go)) New + function, C++ implementation of __calc_dimensions__in a couple of + scripts in scripts/plot. + (__calc_dimensions__) New defun to replace m-script function. + * graphics.h.in Declare calc_dimension + * DLD-FUNCTIONS/fltk_backend.cc ( plot_window (int xx, int yy, int + ww, int hh, figure::properties& xfp)) Use calc_dimensions to + decide if the current figure should be rotated or not. + (void mark_modified (void)) Recompute the number of dimensions in + the plot in case it's been modified and deactivate rotation if + necessary. + (class plot_window) Declare ndim. + (void button_press (Fl_Widget* widg)) Validate that ndim == 3 + before turning on rotation. + (int handle (int event)) Also validate that ndim == 3. + 2010-08-24 David Bateman * ls-mat5.cc (static void read_mat5_binary_data (std::istream&, diff -r da90c16fbe84 -r db1bc83879ff src/DLD-FUNCTIONS/fltk_backend.cc --- a/src/DLD-FUNCTIONS/fltk_backend.cc Wed Aug 25 12:36:23 2010 -0400 +++ b/src/DLD-FUNCTIONS/fltk_backend.cc Thu Aug 26 01:36:36 2010 -0500 @@ -224,7 +224,8 @@ 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), panzoom (0), rotate (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)); @@ -239,7 +240,10 @@ ww, status_h); bottom->box(FL_FLAT_BOX); - + + ndim = calc_dimensions(gh_manager::get_object(fp.get___myhandle__ ())) + .scalar_value(); + autoscale = new Fl_Button (0, hh - status_h, @@ -266,7 +270,7 @@ "P"); panzoom->callback (button_callback, static_cast (this)); panzoom->tooltip ("Mouse Pan/Zoom"); - + rotate = new Fl_Button (3 * status_h, hh - status_h, @@ -276,6 +280,9 @@ rotate->callback (button_callback, static_cast (this)); rotate->tooltip ("Mouse Rotate"); + if(ndim == 2) + rotate -> deactivate(); + help = new Fl_Button (4 * status_h, hh - status_h, @@ -317,7 +324,7 @@ set_name (); resizable (canvas); size_range (4*status_h, 2*status_h); - gui_mode = pan_zoom; + gui_mode = (ndim == 3 ? rotate_zoom : pan_zoom); } ~plot_window (void) @@ -346,6 +353,15 @@ { damage (FL_DAMAGE_ALL); canvas->damage (FL_DAMAGE_ALL); + ndim = calc_dimensions(gh_manager::get_object(fp.get___myhandle__ ())) + .scalar_value(); + if(ndim == 3) + rotate -> activate(); + else + { + rotate -> deactivate(); + gui_mode = pan_zoom; + } } void set_name (void) @@ -362,6 +378,9 @@ // Mod keys status int shift; + // Number of dimensions, 2 or 3. + int ndim; + // Interactive Mode enum { pan_zoom, rotate_zoom } gui_mode; @@ -396,7 +415,7 @@ if (widg == panzoom) gui_mode = pan_zoom; - if (widg == rotate) + if (widg == rotate and ndim == 3) gui_mode = rotate_zoom; if (widg == help) @@ -656,7 +675,10 @@ case 'r': case 'R': - gui_mode = rotate_zoom; + if(ndim == 3) + gui_mode = rotate_zoom; + else + gui_mode = pan_zoom; break; } } @@ -1198,7 +1220,6 @@ void redraw_figure (const graphics_object& go) const { figure_manager::mark_modified (go.get_handle ()); - __fltk_redraw__ (); } diff -r da90c16fbe84 -r db1bc83879ff src/graphics.cc --- a/src/graphics.cc Wed Aug 25 12:36:23 2010 -0400 +++ b/src/graphics.cc Thu Aug 26 01:36:36 2010 -0500 @@ -3434,8 +3434,10 @@ if (el == 90 || el == -90) { - c_upv(0) = -sin(az*M_PI/180.0)*(xlimits(1)-xlimits(0))/pb(0); - c_upv(1) = cos(az*M_PI/180.0)*(ylimits(1)-ylimits(0))/pb(1); + c_upv(0) = + -signum(el)*sin(az*M_PI/180.0)*(xlimits(1)-xlimits(0))/pb(0); + c_upv(1) = + signum(el)*cos(az*M_PI/180.0)*(ylimits(1)-ylimits(0))/pb(1); } else c_upv(2) = 1; @@ -4278,7 +4280,7 @@ xlims (1) += delta_x; ylims (0) += delta_y; ylims (1) += delta_y; - + zoom (xlims, ylims, false); } @@ -4288,7 +4290,13 @@ Matrix v = get_view ().matrix_value (); v (1) += delta_el; - v (0) -= delta_az; + + if(v(1) > 90) + v(1) = 90; + if(v(1) < -90) + v(1) = -90; + + v (0) = fmod(v(0) - delta_az + 720,360); set_view(v); update_transform(); @@ -5498,6 +5506,62 @@ \ return retval +octave_value calc_dimensions(const graphics_object& go) +{ + + octave_value nd = 2; + + if(go.isa("surface")) + nd = 3; + + //Short-circuit bool here is fine + if( (go.isa("line") or go.isa("patch")) and not go.get("zdata").is_empty() ) + nd = 3; + + Matrix kids = go.get_properties().get_children (); + for(octave_idx_type i = 0; i < kids.length (); i++) + { + graphics_handle hnd = gh_manager::lookup (kids(i)); + if (hnd.ok ()) + { + const graphics_object& kid = gh_manager::get_object(hnd); + if(kid.valid_object() ) + nd = calc_dimensions(kid); + if( nd.scalar_value() == 3) + break; + } + } + + return nd; +} + +DEFUN (__calc_dimensions__, args, , + "-*- texinfo -*-\n\ address@hidden {Built-in Function} {} __calc_dimensions__ (@var{axes})\n\ +Internal function. Determine the number of dimensions in a graphics\n\ +object, whether 2 or 3.\n\ address@hidden deftypefn") +{ + gh_manager::autolock guard; + + octave_value retval; + + int nargin = args.length(); + if ( nargin == 1) + { + double h = args(0).double_value(); + if(! error_state ) + retval = calc_dimensions(gh_manager::get_object(h)); + else + error ("__calc_dimensions__: expecting graphics handle as only " + "argument"); + } + else + print_usage(); + + return retval; +} + DEFUN (__go_axes__, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} __go_axes__ (@var{parent})\n\ diff -r da90c16fbe84 -r db1bc83879ff src/graphics.h.in --- a/src/graphics.h.in Wed Aug 25 12:36:23 2010 -0400 +++ b/src/graphics.h.in Thu Aug 26 01:36:36 2010 -0500 @@ -4250,6 +4250,8 @@ void get_children_limits (double& min_val, double& max_val, double& min_pos, const Matrix& kids, char limit_type); +octave_value calc_dimensions(const graphics_object& gh); + // This function is NOT equivalent to the scripting language function gcf. OCTINTERP_API graphics_handle gcf (void);