diff libgui/graphics/Canvas.cc @ 24523:501986e12b8b

Implement "pickableparts" property (bug #52795). * NEWS: Announce that property "PickableParts" has been implemented. * gendpropdoc.m: Document property. State that the property does nothing for figure and root objects. * graphics.in.h: Add allowed value "all" to base_properties::pickableparts and remove pickableparts property from all other objects. * gl-render.h (opengl_renderer::selecting): Add new boolean attribute and setter. * gl-render.cc (opengl_renderer::draw_axes): While in selection mode don't draw axes if "pickableparts" is "none". (opengl_renderer::draw_axes_x/y/zgrid, opengl_renderer::draw_axes_plane): While in selection mode, allow drawing grids/plane if "pickableparts" is "all" (opengl_renderer::draw_line): While in selection mode, allow drawing line and markers "pickableparts" is "all". (opengl_renderer::draw_patch): While in selection mode, allow drawing lines polygons and markers if "pickableparts" is "all". (opengl_renderer::draw_surface): ditto. (opengl_renderer::draw_all_lights): while in selection mode, allow drawing children objects if "pickableparts" is "all". * gl-select.cc (opengl_selector::draw): Put renderer in selection mode. * Canvas.cc (Canvas::canvasMousePressEvent): overhaul handling of currentObj.
author Pantxo Diribarne <pantxo.diribarne@gmail.com>
date Wed, 03 Jan 2018 21:21:41 +0100
parents 798b56f0b207
children 194eb4bd202b
line wrap: on
line diff
--- a/libgui/graphics/Canvas.cc	Thu Jan 04 14:25:11 2018 -0800
+++ b/libgui/graphics/Canvas.cc	Wed Jan 03 21:21:41 2018 +0100
@@ -617,6 +617,7 @@
       {
         graphics_object figObj (obj.get_ancestor ("figure"));
 
+        // Any click in a figure canvas makes it current
         if (figObj)
           {
             graphics_object root = gh_manager::get_object (0);
@@ -626,8 +627,16 @@
 
         graphics_object currentObj, axesObj;
 
+        // Retrieve selected object.   
         select_object (obj, event, currentObj, axesObj);
 
+        // currentObj may be invalid if, e.g., all objects under the mouse
+        // click had "hittest" -> "off" or "pickableparts" -> "none".  In that
+        // case, replace with underlying figObj which always accepts mouse
+        // clicks.
+        if (! currentObj.valid_object ())
+          currentObj = figObj;
+
         if (axesObj)
           {
             if (axesObj.get_properties ().handlevisibility_is ("on")
@@ -635,20 +644,8 @@
                 && axesObj.get_properties ().get_tag () != "colorbar")
               Utils::properties<figure> (figObj)
               .set_currentaxes (axesObj.get_handle ().as_octave_value ());
-            if (! currentObj)
-              currentObj = axesObj;
           }
 
-        if (! currentObj)
-          currentObj = obj;
-
-        if (currentObj.get_properties ().handlevisibility_is ("on"))
-          Utils::properties<figure> (figObj)
-          .set_currentobject (currentObj.get_handle ().as_octave_value ());
-        else
-          Utils::properties<figure> (figObj).set_currentobject (
-            octave::numeric_limits<double>::NaN ());
-
         Figure *fig = dynamic_cast<Figure *> (Backend::toolkitObject (figObj));
 
         MouseMode newMouseMode = NoMode;
@@ -659,33 +656,38 @@
         switch (newMouseMode)
           {
           case NoMode:
-            gh_manager::post_set (figObj.get_handle (), "selectiontype",
-                                  Utils::figureSelectionType (event, isdblclick), false);
-
-            updateCurrentPoint (figObj, obj, event);
-
-            gh_manager::post_callback (figObj.get_handle (),
-                                       "windowbuttondownfcn",
-                                       button_number (event));
+            {
+              // Update the figure "currentobject"
+              auto& fprop = Utils::properties<figure> (figObj);
+            
+              if (currentObj.get_properties ().handlevisibility_is ("on"))
+                fprop.set_currentobject (currentObj.get_handle ()
+                                         .as_octave_value ());
+              else
+                fprop.set_currentobject (Matrix ());
+            
+              // Update figure "selectiontype" and "currentpoint" 
+              gh_manager::post_set (
+                                    figObj.get_handle (), "selectiontype",
+                                    Utils::figureSelectionType (event, isdblclick), false);
 
-            if (currentObj.get ("buttondownfcn").isempty ())
-              {
-                graphics_object parentObj =
-                  gh_manager::get_object (currentObj.get_parent ());
+              updateCurrentPoint (figObj, obj, event);
 
-                if (parentObj.valid_object () && parentObj.isa ("hggroup"))
-                  gh_manager::post_callback (parentObj.get_handle (),
-                                             "buttondownfcn",
-                                             button_number (event));
-              }
-            else
-              gh_manager::post_callback (currentObj.get_handle (),
-                                         "buttondownfcn",
+              gh_manager::post_callback (figObj.get_handle (),
+                                         "windowbuttondownfcn",
                                          button_number (event));
 
-            if (event->button () == Qt::RightButton)
-              ContextMenu::executeAt (currentObj.get_properties (),
-                                      event->globalPos ());
+              // Execute the "buttondownfcn" of the selected object
+              if (! currentObj.get ("buttondownfcn").isempty ())
+                gh_manager::post_callback (currentObj.get_handle (),
+                                           "buttondownfcn",
+                                           button_number (event));
+
+              // Show context menu of the selected object
+              if (event->button () == Qt::RightButton)
+                ContextMenu::executeAt (currentObj.get_properties (),
+                                        event->globalPos ());
+            }
             break;
 
           case TextMode: