# HG changeset patch # User John W. Eaton # Date 1424996699 18000 # Node ID 6ba3d0f7c6e8cc4edafceafdf8c901d75c87aa1c # Parent 726df008104d350202bdbd098e72a6a637b4af3a improve mouse zooming for Qt plotting (bug #44302) * Figure.h (enum MouseMode): Split ZoomMode into ZoomInMode and ZoomOutMode. Change all uses. * Canvas.cc (Canvas::canvasMouseReleaseEvent, Canvas::canvasWheelEvent): Make meaning of zoom factor consistent with zoom function. Make direction of wheel event consistent with other programs. * __init_fltk__.cc (plot_window::handle): Make meaning of zoom factor consistent with zoom function. * MouseModeActionGroup.cc (MouseModeActionGroup::MouseModeActionGroup): Provide buttons for zooming in and out. * graphics.cc (figure::properties::set_toolkit): Handle zoom direction. (do_zoom): Make factor > 1 zoom in. diff -r 726df008104d -r 6ba3d0f7c6e8 libgui/graphics/Canvas.cc --- a/libgui/graphics/Canvas.cc Thu Feb 26 13:54:11 2015 -0500 +++ b/libgui/graphics/Canvas.cc Thu Feb 26 19:24:59 2015 -0500 @@ -71,7 +71,8 @@ w->setCursor (Qt::OpenHandCursor); break; - case ZoomMode: + case ZoomInMode: + case ZoomOutMode: // FIXME: distinguish zoom in/out. w->setCursor (QBitmap (":/images/zoom.png")); break; @@ -206,7 +207,7 @@ draw (m_handle); - if (m_mouseMode == ZoomMode && m_mouseAxes.ok ()) + if (m_mouseMode == ZoomInMode && m_mouseAxes.ok ()) drawZoomBox (m_mouseAnchor, m_mouseCurrent); } } @@ -235,7 +236,8 @@ } break; - case ZoomMode: + case ZoomInMode: + case ZoomOutMode: m_mouseCurrent = event->pos (); redraw (true); break; @@ -546,7 +548,8 @@ case PanMode: case RotateMode: - case ZoomMode: + case ZoomInMode: + case ZoomOutMode: if (axesObj) { bool redraw_figure = true; @@ -609,7 +612,8 @@ void Canvas::canvasMouseReleaseEvent (QMouseEvent* event) { - if (m_mouseMode == ZoomMode && m_mouseAxes.ok ()) + if ((m_mouseMode == ZoomInMode || m_mouseMode == ZoomOutMode) + && m_mouseAxes.ok ()) { gh_manager::auto_lock lock; graphics_object ax = gh_manager::get_object (m_mouseAxes); @@ -626,9 +630,7 @@ if (m_mouseAnchor == event->pos ()) { - // FIXME: check direction here. - - double factor = 2.0; + double factor = m_mouseMode == ZoomInMode ? 2.0 : 0.5; ap.zoom (zm, factor); } @@ -720,7 +722,10 @@ if (zoom_enabled (figObj)) { - newMouseMode = ZoomMode; + if (event->delta () > 0) + newMouseMode = ZoomInMode; + else + newMouseMode = ZoomOutMode; mode = zoom_mode (figObj); } @@ -736,7 +741,8 @@ switch (newMouseMode) { - case ZoomMode: + case ZoomInMode: + case ZoomOutMode: { axes::properties& ap = Utils::properties (axesObj); @@ -744,21 +750,13 @@ double wheel_zoom_speed = ap.get_mousewheelzoom (); // Determine if we're zooming in or out. - double factor = (event->delta () > 0 + double factor = (newMouseMode == ZoomInMode ? 1 / (1.0 - wheel_zoom_speed) : 1.0 - wheel_zoom_speed); - ap.zoom (mode, factor); + // FIXME: should we zoom about point for 2D plots? -#if 0 - Matrix view = ap.get_view ().matrix_value (); - if (view(1) != 90) - { - Matrix zlimits = ap.get_zlim ().matrix_value (); - zlimits = factor * zlimits; - ap.set_zlim (zlimits); - } -#endif + ap.zoom (mode, factor); } break; diff -r 726df008104d -r 6ba3d0f7c6e8 libgui/graphics/Figure.cc --- a/libgui/graphics/Figure.cc Thu Feb 26 13:54:11 2015 -0500 +++ b/libgui/graphics/Figure.cc Thu Feb 26 19:24:59 2015 -0500 @@ -179,8 +179,11 @@ case RotateMode: return "rotate"; - case ZoomMode: - return "zoom"; + case ZoomInMode: + return "zoom in"; + + case ZoomOutMode: + return "zoom out"; case PanMode: return "pan"; @@ -204,8 +207,10 @@ return NoMode; else if (mode == "rotate") return RotateMode; - else if (mode == "zoom") - return ZoomMode; + else if (mode == "zoom in") + return ZoomInMode; + else if (mode == "zoom out") + return ZoomOutMode; else if (mode == "pan") return PanMode; else if (mode == "text") @@ -244,6 +249,15 @@ std::string mode = fp.get___mouse_mode__ (); + if (mode == "zoom") + { + octave_scalar_map zm = fp.get___zoom_mode__ ().scalar_map_value (); + + std::string direction = zm.getfield ("Direction").string_value (); + + mode += " " + direction; + } + return mouse_mode_from_string (mode); } diff -r 726df008104d -r 6ba3d0f7c6e8 libgui/graphics/Figure.h --- a/libgui/graphics/Figure.h Thu Feb 26 13:54:11 2015 -0500 +++ b/libgui/graphics/Figure.h Thu Feb 26 19:24:59 2015 -0500 @@ -42,10 +42,11 @@ NoMode = 0, RotateMode = 1, - ZoomMode = 2, - PanMode = 3, - TextMode = 4, - SelectMode = 5 + ZoomInMode = 2, + ZoomOutMode = 3, + PanMode = 4, + TextMode = 5, + SelectMode = 6 }; class Container; diff -r 726df008104d -r 6ba3d0f7c6e8 libgui/graphics/MouseModeActionGroup.cc --- a/libgui/graphics/MouseModeActionGroup.cc Thu Feb 26 13:54:11 2015 -0500 +++ b/libgui/graphics/MouseModeActionGroup.cc Thu Feb 26 19:24:59 2015 -0500 @@ -38,8 +38,14 @@ { m_actions.append (new QAction (QIcon (":/images/rotate.png"), tr ("Rotate"), this)); - m_actions.append (new QAction (QIcon (":/images/zoom.png"), - tr ("Zoom"), this)); + QAction *zoom_in = new QAction ("Z+", this); + zoom_in->setToolTip (tr ("Zoom In")); + m_actions.append (zoom_in); + + QAction *zoom_out = new QAction ("Z-", this); + zoom_out->setToolTip (tr ("Zoom Out")); + m_actions.append (zoom_out); + m_actions.append (new QAction (QIcon (":/images/pan.png"), tr ("Pan"), this)); m_actions.append (new QAction (QIcon::fromTheme ("insert-text"), @@ -47,8 +53,8 @@ m_actions.append (new QAction (QIcon (":/images/select.png"), tr ("Select"), this)); - m_actions[3]->setEnabled (false); m_actions[4]->setEnabled (false); + m_actions[5]->setEnabled (false); foreach (QAction* a, m_actions) { diff -r 726df008104d -r 6ba3d0f7c6e8 libinterp/corefcn/graphics.cc --- a/libinterp/corefcn/graphics.cc Thu Feb 26 13:54:11 2015 -0500 +++ b/libinterp/corefcn/graphics.cc Thu Feb 26 19:24:59 2015 -0500 @@ -1810,27 +1810,62 @@ } void -figure::properties::set___mouse_mode__ (const octave_value& val) +figure::properties::set___mouse_mode__ (const octave_value& val_arg) { if (! error_state) { - if (__mouse_mode__.set (val, true)) - { - std::string mode = __mouse_mode__.current_value (); - - octave_scalar_map pm = get___pan_mode__ ().scalar_map_value (); - pm.setfield ("Enable", mode == "pan" ? "on" : "off"); - set___pan_mode__ (pm); - - octave_scalar_map rm = get___rotate_mode__ ().scalar_map_value (); - rm.setfield ("Enable", mode == "rotate" ? "on" : "off"); - set___rotate_mode__ (rm); - - octave_scalar_map zm = get___zoom_mode__ ().scalar_map_value (); - zm.setfield ("Enable", mode == "zoom" ? "on" : "off"); - set___zoom_mode__ (zm); - - mark_modified (); + std::string direction = "in"; + + octave_value val = val_arg; + + if (val.is_string ()) + { + std::string modestr = val.string_value (); + + if (modestr == "zoom in") + { + val = modestr = "zoom"; + direction = "in"; + } + else if (modestr == "zoom out") + { + val = modestr = "zoom"; + direction = "out"; + } + + if (__mouse_mode__.set (val, true)) + { + std::string mode = __mouse_mode__.current_value (); + + octave_scalar_map pm = get___pan_mode__ ().scalar_map_value (); + pm.setfield ("Enable", mode == "pan" ? "on" : "off"); + set___pan_mode__ (pm); + + octave_scalar_map rm = get___rotate_mode__ ().scalar_map_value (); + rm.setfield ("Enable", mode == "rotate" ? "on" : "off"); + set___rotate_mode__ (rm); + + octave_scalar_map zm = get___zoom_mode__ ().scalar_map_value (); + zm.setfield ("Enable", mode == "zoom" ? "on" : "off"); + zm.setfield ("Direction", direction); + set___zoom_mode__ (zm); + + mark_modified (); + } + else if (modestr == "zoom") + { + octave_scalar_map zm = get___zoom_mode__ ().scalar_map_value (); + std::string curr_direction + = zm.getfield ("Direction").string_value (); + + if (direction != curr_direction) + { + zm.setfield ("Direction", direction); + set___zoom_mode__ (zm); + + mark_modified (); + } + } } } } @@ -7572,8 +7607,8 @@ } // Perform the zooming - lo = val + factor * (lo - val); - hi = val + factor * (hi - val); + lo = val + (lo - val) / factor; + hi = val + (hi - val) / factor; if (is_logscale) { diff -r 726df008104d -r 6ba3d0f7c6e8 libinterp/dldfcn/__init_fltk__.cc --- a/libinterp/dldfcn/__init_fltk__.cc Thu Feb 26 13:54:11 2015 -0500 +++ b/libinterp/dldfcn/__init_fltk__.cc Thu Feb 26 19:24:59 2015 -0500 @@ -1588,15 +1588,18 @@ double wheel_zoom_speed = ap.get_mousewheelzoom (); // Determine if we're zooming in or out. - const double factor = - (Fl::event_dy () > 0) ? 1 / (1.0 - wheel_zoom_speed) - : 1.0 - wheel_zoom_speed; + const double factor = (Fl::event_dy () < 0 + ? 1 / (1.0 - wheel_zoom_speed) + : 1.0 - wheel_zoom_speed); + // Get the point we're zooming about. double x1, y1; pixel2pos (ax, Fl::event_x (), Fl::event_y () - menu_dy (), x1, y1); + // FIXME: should we only zoom about point for 2D plots? + ap.zoom_about_point ("both", x1, y1, factor, false); mark_modified (); return 1;